Add table of contents to hyde-hyde theme in Hugo - hugo

I'm using the hyde-hyde theme for my website with Hugo (https://github.com/htr3n/hyde-hyde), and I can't figure out a way to add a table fo contents to my posts, especially the long ones. Is there a simple way to do it with this theme ?
Thanks.

UPDATED 2018-09-30:
I misread the original question about TOC and instead gave an answer on tables in Markdown.
Regarding Table of Contents, there are essentially two approaches:
a) Using Hugo support for TOC and add some CSS rules to style the TOC as you wish
b) Using external libraries such as Tocbot that can scan the HTML content and extract the headings to create the TOC. Tocbot is very powerful and configurable.
In particular in hyde-hyde, you can do the following the achieve a TOC:
a) Add {{ .TableOfContents }} to layouts/partials/page-single/content.html, for instance
{{ if .Site.Params.toc }}
{{ .TableOfContents }}
{{ end }}
b) Style the original Hugo generated TOC with the root element nav#TableOfContents, for example
#TableOfContents > ul {
list-style-type: none;
padding-left: 0;
}
#TableOfContents > ul > li ul {
list-style-type: none;
padding-left: 1em;
}
You can investigate further the example code here where I developed a collapsible TOC.
I'm the author of hyde-hyde, so hopefully I can weigh in some suggestions.
hyde-hyde is a just theme used by gohugo to generate static Web pages (HTML/CSS/JS) from Markdown (MD) contents. So what you need is to add tables in your Markdown files.
Note that tables are not specified in original Markdown but supported in many variants like MultiMarkdown (MMD) or Github Flavored Markdown (GFM).
Another potential approach is using inline HTML supported by Markdown to add <table>...</table> as you wish. This works better in case you need complex tables (e.g. with rowspan or colspan), as you can see here.
The aforementioned methods can be used with other Hugo themes as well. Either way, Hugo can handle tables well.

I am new to gohugo, so I can't provide precise support. But it seems like gohugo comes with a built-in system for adding tables of contents to posts. Here's the gohugo documentation for the feature: https://gohugo.io/content-management/toc/
I am not sure where and how the TOC would appear in a post published with the Hyde-Hyde theme. The author of the theme might have some insight there.

Related

Split single file to multiple "posts" in Hugo?

Hugo's one-file->one-page model is nice and simple, especially for a blog. But sometimes you want to write an "article" for a blog and split it into 2 or more pieces for separate pages (perhaps to be posted on separate days, or whatever).
Is there a way to do this within Hugo? Perhaps a combination of something you put in a layout/theme/shortcode and internal markup within the page (to signal where to split the article)?
Possible models might include:
1 input post "splits" into 2/3/4 posts when the site is built to public
1 input post is duplicated into 2/3/4 posts when the site is built to public but somehow each duplicate isn't an exact duplicate but instead has the whole post but certain parts of the post are hidden/invisible, via CSS, such that they represent the 2/3/4 "pages" of the post.
Or, is this something you do external to Hugo?
UPDATE: I can see I need to clarify this. Consider this random illustrative blog post - it is the third of three closely related posts, and even has a set of links at the top so you can find the earlier posts in the series. Lots of technical blogs do this sort of thing (at least the ones I read).
Now, I'm not looking for a CMS or anything complex. What I do now with Hugo is hugo new posts/an-article-about-constexpr.md and I write one markdown file and it becomes one "post" in standard Hugo fashion. Exactly what you want a SSG to do.
What I want to do is write one markdown file but have some kind of markup in it separating it into sections (like <!-- More --> on steroids) so that instead of generating one page of my site it generates three (in this example) - three separate articles with links from the main page in the "posts" section, etc. etc. And for bonus points, I'd like to generate these "table of contents" sections with links to each of the pages.
So I've been doing that with a cobbled-up awk script that generates pages right next to the post, in the posts directory. I set the post to draft so it doesn't get published, but the pages generated by the awk script have draft=false so they do get published. And the dates get set so they're "in order".
And that's working, but before I invest more time in my little script, I wanted to see if there was a proper way to do this within hugo.
Not sure what you mean by one-file->one-page model.
I have very few parts of any hugo site which one markdown file=one rendered html page.
Could just be the way I build, but everything I've done so far has been vanilla hugo.
To answer your question: Yes, you are correct that would work. There a few ways to do this (I list one below), but maybe a deeper look would be separating the concept of a "tool-chain" and what Hugo is in that tool chain, from a CMS, which Hugo is not.
So, to possibly answer your specific question though:
You can store content in markdown, markdown front matter, or a Data form (XML/JSON) in hugo. Using the page resources {{ .GetPage }} you can access any content and load it in any template or using shortcodes, load it in other markdown.
If I needed to do this as part of a tool chain, i.e. use specific markdown and re-use it in multiple places, I would create a front matter variable, or taxonomy or tag depending on what groupings I needed where, so this was scalable. params such as
"articleAuthor: Jessie P."
"date: DATE HERE"
"tags: etc. etc."
Then lets say I know that's going to be a blog, well fine, then it will be in the corresponding content folder, but if I needed all of Jessie's articles, or articles on that date, or that specific article, I would use the shortcode I make or directly in a template, using .GetPage Match - import the markdown pages I need based on the parameters I need.
But on the other hand, I would need to understand the problem being solved, but, here are a few hugo docs to help you out:
https://gohugo.io/functions/getpage/#readout
https://gohugo.io/content-management/page-bundles/
Remember, Hugo is not a CMS, it is a site generator. If you want a CMS, you can always use Wordpress headless, or any other solution out there.
(off the top of my head using page bundles)
{{ $headlessBundle := .Site.GetPage "/blogs/specific-blog/index" }}
{{ with $getContent := $headlessBundle.Resources.Match "intro.md" }}
{{ (index $getContent 0).Content }}
(You would use various "Where" statements to "filter" content based on the params or however you delineate what you want).
Or for instance if I wanted only the text that had an H1 tag:
{{ $.Scratch.Set "summary" ((delimit (findRE "(<h1.*?>.*?</h1>\\s*)+" .Content) "[…]") | plainify | replaceRE "&" "&" | safeHTML) }}
{{ $.Scratch.Get "summary" }}
Based on the update to the question:
https://discourse.gohugo.io/t/split-markdown-content-in-two-files-but-dont-render-shortcodes-as-raw-text/32080/2
https://discourse.gohugo.io/t/getting-a-list-from-within-a-shortcode/28126
https://discourse.gohugo.io/t/splitting-content-into-sections-based-on-header-level/33749
https://discourse.gohugo.io/t/multiple-content-blocks-on-a-single-page/9092/3
jrmooring answered it best in the above with clear examples and code.
Though, note: If I was doing this in a technical blog this would be integrated into the CMS and coordinated with the builder.

How to add a telephone link via wagtail?

I am trying to add links in the form 555-555-555 arbitrarily into paragraphs of text on my wagtail site. These phone numbers are currently peppered throughout the site as plain text, but I want to convert them to links.
I found this old wagtail github issue where they explained why they would not add them, but the 'Special-purpose pages' use case they described seems to be different than mine: my site has these numbers in paragraphs of text on most of the content pages (blog, product, marketing, etc).
Can anyone explain how I can add telephone links that can be used throughout the site?
I am using wagtail 1.x
To have telephone link within rich text, you'll need to create a plugin for Hallo.js. Have a look at the documentation and how Wagtail 1.13 creates and register such plugins.
Be aware though that it's usually quite involved and that Wagtail 2.0 rich text editor is now Draftail and Hallo.js is deprecated. Therefore, if you create a Hallo.js plugin and upgrade to Wagtail 2.0, you'll have to add some configuration to continue using Hallo.js or recreate the plugin for Draftail.
FWIW, if you are interested in having a look at what would be involved with creating an plugin for Draftail, you'll need to create an entity (also note that the API for creating entities should receive some enhancements in Wagtail 2.2).
With Raw HTML there is nothing to prevent editors from inserting malicious scripts into the page. Do not use this block. http://docs.wagtail.io/en/v2.1/topics/streamfield.html#rawhtmlblock
A workaround would be a custom filter. Eg:
{{ self.text|richtext|phonify }}
In your templatetags.py:
>>> def phonify(val):
... for tel in re.findall(r'tel:(\d+)', val):
... tag = '{}'.format(tel, tel)
... val = val.replace('tel:{}'.format(tel), tag)
... return val
...
>>> phonify('Hello tel:123 world tel:456!')
'Hello 123 world 456!'
>>>
Now you can instruct editors (via help_text) to add phone numbers like tel:5555555555.
This example does not handle - and +1. But if you figure that out, I'll update the answer ;)
I ended up chopping up my paragraphs and including raw html where I needed to add the tel links. A bit tedious, and the styles were slightly different on some pages, but shorter than doing it any other way.

blogger - filtering archive list widget by labels

I have made a blogger site for a friend. She wanted 2 blogs on the one site which I managed to achieve using search and labels.
http://thewishingtreeandotherdreams.blogspot.co.nz/search/label/moon
http://thewishingtreeandotherdreams.blogspot.co.nz/search/label/blog
Now what I want to do is also filter the archive widget based on the above labels.
I know I will have to have a second archive widget so one shows only "moon" labeled posts and the other only shows "blog" labeled posts
My programming knowledge however is VERY limited. Has anyone else already done this. Do you have code you could share with me?
Here's a script with similar functionality but not include nesting by dates. Only copy and edit the next code into new HTML/JavaScript widget.
<script src="http://cloud.github.com/downloads/jhwilson/Create-a-Blogger-archive-page/Make-Blogger-Archive-Page.js"></script>
<script src="http://NAME_OF_YOUR_BLOG.blogspot.com/feeds/posts/default/-/LABEL_NAME?max-results=500&alt=json-in-script&callback=LoadTheArchive"></script>
If adds some CSS could be look better.

How to conditionally load content (mobile-first)

I am about to create my first 'mobile-first' website and am unsure on the best way to conditionally load content as the viewport increases.
For example, lets say I wish to load a twitter feed only for desktop browsers, not mobile, how would I do this?
Option 1) Display: none - This is bad as content still loads for mobile
Option 2) Have content in markup, but remove.element with javascript - I believe this content still loads first, then is removed after? If so, not good.
Option 3) Using javascript, if viewport is wide enough, load content - This seems to be the recommended approach, from what i've read, but Is it a good idea to have markup in javascript? I am thinking about accessibility, semantics and seo.
Are there any other better solutions?
Any advice would be greatly appreciated.
You might want to check out Modernizr . It's easy to install and you can use it check for HTML5 support in a visitors browser, as well as the window width, for example:
if (Modernizr.mq('(min-width: 400px)')) {
/* do this for tablets and desktops */
}else{
/* do this for handhelds */
}
Good luck!
UPDATE
thanks, but then in that case would it not be better to do that straight with javascript - if (document.documentElement.clientWidth > 640)
You are right, for that specific instance of deciding whether or not to load a twitter feed, there probably isn't a big advantage of using my suggestion over your option 3. Thinking ahead though, with repsonsive design, mobile sites and now HTML5, the next questions you are going to come up against are how to customise the CSS for different viewpoints, or how to test if a visitor's browser supports a certain HTML5 feature.
You could certainly take a roll-your-own approach and write custom javascript for each case, or you could use Modernizr to test if the visitors browswer supports media queries, and if it doesn't load respond.js, or use Modernizr to test if the vistor's browser supports geolocation or html5 forms or certain video formats ..., and if it doesn't conditionally load a cross browser polyfill.
There are usually multiple ways of achieving the same goal, I'm strong on not reinventing the wheel ;)
Who says? Display:none; is one the best practices in showing and hiding elements for any specific viewport.
And one thing Adam, mark-up is the least downloadable stuff for each device, they have to process some other things if you hide element by Jquery or Javascript. Because sometimes small devices either don't support loading them or take extra time that's why they are visible.
But it has the pitfall for SEO purposes.
For SEO optimization along with hiding elements you can do one of these things with your CSS.
First,
#media screen and (max-width:480px) {
div {
position: absolute;
left: -9999em;
width: 0;
height: 0;
overflow: hidden;
}
}
But it was the less efective because Google Webmaster takes care all such hacks. And You may be blacklisted from being Google indexed.So You should use one of these modern methods to hide elements.
Second,
div {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
or, third,
div {
color:transparent;
text-indent:100%;
overflow:hidden;
white-space:no-wrap;
font:0/0 a;
text-shadow:none;
}

How to theme a menu block in Drupal?

This should really be a basic question but I simply don't get it after hours of searching. The question is, how do I theme menu blocks in Drupal 7?
I've created three different blocks all based on the main menu. Now I want to:
create unique HTML for all three blocks, that means modifing the surrounding wrapper and the <ul> and <li> that builds the menu. I wanna set special classes and remove all of the Drupal-added stuff
attach different classes to the different levels within each block. One of blocks will show two levels of the menu, i.e. it will display a submenu. I want to set a special class on the for the submenu...
This seems impossible... :(
Thank you in advance for the help!!!!
Theming is a tricky beast that often varies a lot depending what you need to do. Even with your very detailed description I can still say "it depends", but here are a couple steps that may help you get pointed in the right direction.
Step 1: Use a block tpl.php as suggested by Caffeine Addict. If you're not sure what to name the .tpl.php, I recommend the Theme Developer module. It's buggy, but you can use it to select an particular element and have it tell you suggestions for naming of .tpl.php files.
Step 2: Use a theme / preprocess function in template.php to modify the pre-defined variables and markup. Be sure to check on the theme_menu_tree & template_preprocess_menu_tree functions on api.drupal.org for starting points. If you're using the devel module, use dpm($variables); in each of those to see what you have to work with from the start.
I hope that helps! I agree with Caffeine Addict when he says that superfish might be an alternative. You should also probably check out the menu block module for breaking out conditional sub-sections into their own blocks.
In addition to what davidneedham said, to change what Drupal added to your menu HTML tags, you can override them. Here it is added classes:
<ul class="expanded">
<li class="firstleaf">...<li>
...
</ul>
i did not find a way to remove this classes, but you can override them in your block--system--main_menu.tpl.php file, like this:
li.expanded,
li.collapsed,
li.leaf {
padding: 0 0 0 0;
margin: 0;
}
ul.menu li {
margin: 0 0 0 0;
}
and then print your menu content:
<?php echo $content; ?>
I'm new in Drupal, wish my post can help you! :)
I would suggest to start with installing the Zen theme and follow the instructions inside the theme to setup a starter sub theme. This has all the information needed to learn theming in drupal and even how to add your own stylesheets etc.
This will allow you to start editing the templates for menu blocks and set your own html wrappers and classes.
For setting extra classes on blocks i would use this module:
http://drupal.org/project/block_class
Then just edit the block and you will see an extra section for adding additional classes to the block.

Resources