From 667e11c4ec3835d959aab1797647bd0a49869674 Mon Sep 17 00:00:00 2001 From: etienne Date: Tue, 21 Oct 2014 23:35:24 +0200 Subject: Init commit --- content/tutorials/github_pages_blog.md | 201 +++++++++++++++++++++++++++++++ content/tutorials/mathjax.md | 82 +++++++++++++ content/tutorials/migrate-from-jekyll.md | 156 ++++++++++++++++++++++++ 3 files changed, 439 insertions(+) create mode 100644 content/tutorials/github_pages_blog.md create mode 100644 content/tutorials/mathjax.md create mode 100644 content/tutorials/migrate-from-jekyll.md (limited to 'content/tutorials') diff --git a/content/tutorials/github_pages_blog.md b/content/tutorials/github_pages_blog.md new file mode 100644 index 0000000..7587d13 --- /dev/null +++ b/content/tutorials/github_pages_blog.md @@ -0,0 +1,201 @@ +--- +author: Spencer Lyon +date: 2014-03-21 +linktitle: Hosting on GitHub +menu: + main: + parent: tutorials +next: /tutorials/mathjax +prev: /community/contributing +title: Hosting on GitHub Pages +weight: 10 +--- + +## Intro + +Many Hugo users have expressed interest in seeing a tutorial for how to set up a blog that generated by Hugo and hosted on GitHub Pages. This tutorial will do just that. We only require that the reader has Hugo installed correctly and is comfortable with git and GitHub. + +During this tutorial, I will walk you through the main steps I took to create an example blog available at [http://spencerlyon2.github.io/hugo_gh_blog](http://spencerlyon2.github.io/hugo_gh_blog). The source code for this blog is on [GitHub](https://github.com/spencerlyon2/hugo_gh_blog). Readers are encouraged to download the example repository and follow along. + +### Find a Home for Your Files + +As our goal is to host a website using GitHub Pages, it is natural for us to host the content of the page in a GitHub repository. Thus, the first step is to either create a new repository on GitHub or create a new directory within an existing repository where the content of the website will live. To do this I created the repository [spencerlyon2/hugo_gh_blog](https://github.com/spencerlyon2/hugo_gh_blog). + +## Create the Blog + +### Write a `config.yaml` File + +The very first step in creating a new Hugo site is to [write the config file](/overview/configuration). This config file is important for at least two reasons: (1) this is where site-wide settings (like the websites `baseurl`) go and (2) the config file dictates to some extent how Hugo will generate the website. For the example website I created a file `config.yaml` with the following contents + + --- + contentdir: "content" + layoutdir: "layouts" + publishdir: "public" + indexes: + category: "categories" + baseurl: "http://spencerlyon2.github.io/hugo_gh_blog" + title: "Hugo Blog Template for GitHub Pages" + ... + +### Define Structure of Website + +Hugo assumes that you organize the content of your site in a meaningful way and uses the same structure to render the website. Notice that we have the line `contentdir: "content"` in our configuration file. This means that all the actual content of the website should be placed somewhere within a folder named `content`. Hugo treats all directories in `content` as sections. For our example we only need one section: a place to hold our blog posts. So we created two new folders: + +``` +▾ / + ▾ content/ + ▾ posts/ +``` + +### Create html Templates + +The next step is to define the look and feel of your new website. Because Hugo will generate the site using html templates written by the user (you), this step is very subjective. I will merely present one possible theme that could be used to generate a blog. I decided to base the example project on a Jekyll theme called [lanyon](http://lanyon.getpoole.com). The lanyon theme is pure css and a slightly modified version of the css is in the `/static/css` directory of the example repository. If you are following along, you should grab the `static` folder from the example repository and put it alongside the `content` folder you just created. + +Because there are so many files needed to fully compose a complete website, I will not be able to go trough each of them here. I will, however, show what the directory structure should look like when all is said and done: + +``` +▾ / + ▾ content/ + ▾ posts/ + .md + ▾ static/ + ▾ css/ + lanyon.css + poole.css + ▾ layouts/ + ▾ partials/ + .html + ▾ posts/ + li.html + single.html + summary.html + ▾ indexes/ + category.html + indexes.html + posts.html + index.html + README.md +``` + +Each of the files in the example repository is well commented with a description of what the file as a whole does as well as an explanation of all major components in the file. If you are new to web development and/or Hugo I encourage you to search through these files to get a feel for how Hugo templates work and how the site is stitched together. + +### Add Some Content + +The final step in creating the blog is to add some actual blog posts. To do this simply create one markdown file (with extension .md) for each new blog post. At the top of each file you should include a metadata section that tells Hugo some things about the post (see [docs](/content/front-matter)). For example, consider the yaml metadata section from the top of the file `/content/posts/newest.md` from the example repository + + --- + title: "Just another sample post" + date: "2014-03-29" + description: "This should be a more useful description" + categories: + - "hugo" + - "fun" + - "test" + --- + +The keys set in this section are the mandatory `title` and `date` as well as the optional `description` and `categories`. Each of these items is used throughout the templates found in the `/layouts` directory and gives Hugo information about the post from other pages in the website. + +## Configure `git` Workflow + +Once the site is set up and working properly, we need to push it to the correct branch of a GitHub repository so the website can be served through GitHub Pages. There are many ways to do this. Here I will show the workflow I currently use to manage my websites that are hosted through GitHub Pages. + +GitHub Pages will serve up a website for any repository that has a branch called `gh-pages` with a valid `index.html` file at that branch's root. A typical workflow might be to keep the content of a website on the `master` branch of a repository and the generated website on the `gh-pages` branch. This provides nice separation between input and output, but can be very tedious to work with. As a workaround we will use the `git subtree` family of commands to have the `public` directory (or whatever `publishdir` is set to in your `config.yaml`) mirror the root of the `gh-pages` branch of the repository. This will allow us to do all our work on the `master` branch, run Hugo have have the site output into the `public` directory, and then push that directory directly to the correct place for GitHub Pages to serve our site. + +To get this properly set up we will execute a series of commands at the terminal. I will include all of them in one place here for easy copy and paste, and will explain what each line does via comments. Note that this is to be run from the `` directory (wherever the `content` and `layout` folders of your Hugo project live). Also note that you will need to change the commands that have the example repository GitHub address so that they point to your repo. + + # Create a new orphand branch (no commit history) named gh-pages + git checkout --orphan gh-pages + + # Unstage all files + git rm --cached $(git ls-files) + + # Grab one file from the master branch so we can make a commit + git checkout master README.md + + # Add and commit that file + git add . + git commit -m "INIT: initial commit on gh-pages branch" + + # Push to remote gh-pages branch + git push origin gh-pages + + # Return to master branch + git checkout master + + # Remove the public folder to make room for the gh-pages subtree + rm -rf public + + # Add the gh-pages branch of the repository. It will look like a folder named public + git subtree add --prefix public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages --squash + + # Pull down the file we just committed. This helps avoid merge conflicts + git subtree pull --prefix=public + + # Run hugo. Generated site will be placed in public directory (or omit -t ThemeName if you're not using a theme) + hugo -t ThemeName + + + # Add everything + git add -A + + # Commit and push to master + git commit -m "Updating site" && git push origin master + + # Push the public subtree to the gh-pages branch + git subtree push --prefix=public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages + +After executing these commands and waiting for the GitHub servers to update, the website we just created was live at [http://spencerlyon2.github.io/hugo_gh_blog](http://spencerlyon2.github.io/hugo_gh_blog). + +### `deploy.sh` + +Now, as you add new posts to your blog, you will follow steps that look something like the following: + +* Create the markdown source for the new post within the `content/posts` directory +* Preview your work by running Hugo in server mode with `hugo server --watch` +* Run Hugo not in server mode so that the generated urls will be correct for the website +* Add and commit the new post in `master` branch +* Push the `master` branch +* Push the public subtree to the remote `gh-pages` branch + +The first two items in the previous list are simply a way to conveniently preview your content as you write. This is a dynamic and fairly streamlined process. All the remaining items, however, are the same every time you want to add new content to the website. To make this repetitive process easier, I have adapted a script from the source repository for the [Chimer Arta & Maker Space](https://github.com/chimera/chimeraarts.org) website that is highlighted in the [Hugo Showcase](/showcase). The script lives in a file called `deploy.sh` and has the following contents: + +**Note:** + +The first command `hugo` assumes you are running with all the default settings. + +To use a theme, make sure to specify it with `-t ThemeName` instead (or include the theme in the config file). + + hugo -t ThemeName + +To build all draft posts *(If you only have drafts, no site will be generated)* + + hugo --buildDrafts + +**Deploy.sh:** + + #!/bin/bash + + echo -e "\033[0;32mDeploying updates to GitHub...\033[0m" + + # Build the project. + hugo + + # Add changes to git. + git add -A + + # Commit changes. + msg="rebuilding site `date`" + if [ $# -eq 1 ] + then msg="$1" + fi + git commit -m "$msg" + + # Push source and build repos. + git push origin master + git subtree push --prefix=public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages + +Now I can replace the last four items from our workflow list with a single command `bash deploy.sh`. This script accepts as an optional argument the commit message that git should use when committing your changes. If you wish to include a custom commit message, do so by putting it quotes after calling bash on the script: `bash deploy.sh ""`. If you choose not to specify the commit message, one will be generated for you using the current time. + +## Conclusion + +Hopefully this tutorial helped you get your website off its feet and out into the open! If you have any further questions feel free to contact the community through the [mailing lists](/community/mailing-list). diff --git a/content/tutorials/mathjax.md b/content/tutorials/mathjax.md new file mode 100644 index 0000000..5ce6bdc --- /dev/null +++ b/content/tutorials/mathjax.md @@ -0,0 +1,82 @@ +--- +author: Spencer Lyon +date: 2014-03-20 +menu: + main: + parent: tutorials +next: /tutorials/migrate-from-jekyll +prev: /tutorials/github_pages_blog +title: MathJax Support +weight: 10 +--- + +## What is MathJax? + +[MathJax](http://www.mathjax.org/) is a JavaScript library that allows allows the display of mathematical expressions described via a LaTeX-style syntax in the HTML (or Markdown) source of a web page. As it is a pure a JavaScript library, getting it to work within Hugo is fairly straightforward, but does have some oddities that will be discussed here. + +This is not an introduction into actually using MathJax to render typeset mathematics on your website. Instead, this page is a collection of tips and hints for one way to get MathJax working on a website built with Hugo. + +## Enabling MathJax + +The first step is to enable MathJax on pages that you would like to have typeset math. There are multiple ways to do this (adventerous readers can consult the [Loading and Configuring](http://docs.mathjax.org/en/latest/configuration.html) section of the MathJax documentation for additional methods of including MathJax), but the easiest way is to use the secure MathJax CDN by including the following HTML snippet in the source of a page: + + + +One way to ensure that this code is included in all pages is to put it in one of the templates that live in the `layouts/partials/` directory. For example, I have included this in the bottom of my template `footer.html` because I know that the footer will be included in every page of my website. + +### Options and Features + +MathJax is a stable open-source library with many features. I encourage the interested reader to view the [MathJax Documentation](http://docs.mathjax.org/en/latest/index.html), specifically the sections on [Basic Usage](http://docs.mathjax.org/en/latest/index.html#basic-usage) and [MathJax Configuration Options](http://docs.mathjax.org/en/latest/index.html#mathjax-configuration-options). + +## Issues with Markdown + +After enabling MathJax, any math entered in-between proper markers (see documentation) will be processed and typeset in the web page. One issue that comes up, however, with Markdown is that the underscore character (`_`) is interpreted by Markdown as a way to wrap text in `emph` blocks while LaTeX (MathJax) interprets the underscore as a way to create a subscript. This "double speak" of the underscore can result in some unexpected and unwanted behavior. + +### Solution + +There are multiple ways to remedy this problem. One solution is to simply escape each underscore in your math code by entering `\_` instead of `_`. This can become quite tedious if the equations you are entering are full of subscripts. + +Another option is to tell Markdown to treat the MathJax code as verbatim code and not process it. One way to do this is to wrap the math expression inside a `
` `
` block. Markdown would ignore these sections and they would get passed directly on to MathJax and processed correctly. This works great for display style mathematics, but for inline math expressions the line break induced by the `
` is not acceptable. The syntax for instructing Markdown to treat inline text as verbatim is by wrapping it in backticks (`` ` ``). You might have noticed, however, that the text included in between backticks is rendered differently than standard text (on this site these are items highlighted in red). To get around this problem, we could create a new CSS entry that would apply standard styling to all inline verbatim text that includes MathJax code. Below I will show the HTML and CSS source that would accomplish this (note this solution was adapted from [this blog post](http://doswa.com/2011/07/20/mathjax-in-markdown.html)---all credit goes to the original author). + + + + + +As before, this content should be included in the HTML source of each page that will be using MathJax. The next code snippet contains the CSS that is used to have verbatim MathJax blocks render with the same font style as the body of the page. + + + code.has-jax {font: inherit; + font-size: 100%; + background: inherit; + border: inherit; + color: #515151;} + +In the CSS snippet, notice the line `color: #515151;`. `#515151` is the value assigned to the `color` attribute of the `body` class in my CSS. In order for the equations to fit in with the body of a web page, this value should be the same as the color of the body. + +### Usage + +With this setup, everything is in place for a natural usage of MathJax on pages generated using Hugo. In order to include inline mathematics, just put LaTeX code in between `` `$ TeX Code $` `` or `` `\( TeX Code \)` ``. To include display style mathematics, just put LaTeX code in between `
$$TeX Code$$
`. All the math will be properly typeset and displayed within your Hugo generated web page! diff --git a/content/tutorials/migrate-from-jekyll.md b/content/tutorials/migrate-from-jekyll.md new file mode 100644 index 0000000..5aeaec0 --- /dev/null +++ b/content/tutorials/migrate-from-jekyll.md @@ -0,0 +1,156 @@ +--- +date: 2014-03-10 +linktitle: Migrating from Jekyll +menu: + main: + parent: tutorials +prev: /tutorials/mathjax +title: Migrate to Hugo from Jekyll +weight: 10 +--- + +## Move static content to `static` +Jekyll has a rule that any directory not starting with `_` will be copied as-is to the `_site` output. Hugo keeps all static content under `static`. You should therefore move it all there. +With Jekyll, something that looked like + + ▾ / + ▾ images/ + logo.png + +should become + + ▾ / + ▾ static/ + ▾ images/ + logo.png + +Additionally, you'll want any files that should reside at the root (such as `CNAME`) to be moved to `static`. + +## Create your Hugo configuration file +Hugo can read your configuration as JSON, YAML or TOML. Hugo supports parameters custom configuration too. Refer to the [Hugo configuration documentation](/overview/configuration/) for details. + +## Set your configuration publish folder to `_site` +The default is for Jekyll to publish to `_site` and for Hugo to publish to `public`. If, like me, you have [`_site` mapped to a git submodule on the `gh-pages` branch](http://blog.blindgaenger.net/generate_github_pages_in_a_submodule.html), you'll want to do one of two alternatives: + +1. Change your submodule to point to map `gh-pages` to public instead of `_site` (recommended). + + git submodule deinit _site + git rm _site + git submodule add -b gh-pages git@github.com:your-username/your-repo.git public + +2. Or, change the Hugo configuration to use `_site` instead of `public`. + + { + .. + "publishdir": "_site", + .. + } + +## Convert Jekyll templates to Hugo templates +That's the bulk of the work right here. The documentation is your friend. You should refer to [Jekyll's template documentation](http://jekyllrb.com/docs/templates/) if you need to refresh your memory on how you built your blog and [Hugo's template](/layout/templates/) to learn Hugo's way. + +As a single reference data point, converting my templates for [heyitsalex.net](http://heyitsalex.net) took me no more than a few hours. + +## Convert Jekyll plugins to Hugo shortcodes +Jekyll has [plugins](http://jekyllrb.com/docs/plugins/); Hugo has [shortcodes](/doc/shortcodes/). It's fairly trivial to do a port. + +### Implementation +As an example, I was using a custom [`image_tag`](https://github.com/alexandre-normand/alexandre-normand/blob/74bb12036a71334fdb7dba84e073382fc06908ec/_plugins/image_tag.rb) plugin to generate figures with caption when running Jekyll. As I read about shortcodes, I found Hugo had a nice built-in shortcode that does exactly the same thing. + +Jekyll's plugin: + + module Jekyll + class ImageTag < Liquid::Tag + @url = nil + @caption = nil + @class = nil + @link = nil + // Patterns + IMAGE_URL_WITH_CLASS_AND_CAPTION = + IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK = /(\w+)(\s+)((https?:\/\/|\/)(\S+))(\s+)"(.*?)"(\s+)->((https?:\/\/|\/)(\S+))(\s*)/i + IMAGE_URL_WITH_CAPTION = /((https?:\/\/|\/)(\S+))(\s+)"(.*?)"/i + IMAGE_URL_WITH_CLASS = /(\w+)(\s+)((https?:\/\/|\/)(\S+))/i + IMAGE_URL = /((https?:\/\/|\/)(\S+))/i + def initialize(tag_name, markup, tokens) + super + if markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK + @class = $1 + @url = $3 + @caption = $7 + @link = $9 + elsif markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION + @class = $1 + @url = $3 + @caption = $7 + elsif markup =~ IMAGE_URL_WITH_CAPTION + @url = $1 + @caption = $5 + elsif markup =~ IMAGE_URL_WITH_CLASS + @class = $1 + @url = $3 + elsif markup =~ IMAGE_URL + @url = $1 + end + end + def render(context) + if @class + source = "
" + else + source = "
" + end + if @link + source += "" + end + source += "" + if @link + source += "" + end + source += "
#{@caption}
" if @caption + source += "
" + source + end + end + end + Liquid::Template.register_tag('image', Jekyll::ImageTag) + +is written as this Hugo shortcode: + + +
+ {{ with .Get "link"}}{{ end }} + + {{ if .Get "link"}}{{ end }} + {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}} +
{{ if isset .Params "title" }} + {{ .Get "title" }}{{ end }} + {{ if or (.Get "caption") (.Get "attr")}}

+ {{ .Get "caption" }} + {{ with .Get "attrlink"}} {{ end }} + {{ .Get "attr" }} + {{ if .Get "attrlink"}} {{ end }} +

{{ end }} +
+ {{ end }} +
+ + +### Usage +I simply changed: + + {% image full http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg "One of my favorite touristy-type photos. I secretly waited for the good light while we were "having fun" and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing." ->http://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/ %} + +to this (this example uses a slightly extended version named `fig`, different than the built-in `figure`): + + {{% fig class="full" src="http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg" title="One of my favorite touristy-type photos. I secretly waited for the good light while we were having fun and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing." link="http://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/" %}} + +As a bonus, the shortcode named parameters are, arguably, more readable. + +## Finishing touches +### Fix content +Depending on the amount of customization that was done with each post with Jekyll, this step will require more or less effort. There are no hard and fast rules here except that `hugo server --watch` is your friend. Test your changes and fix errors as needed. + +### Clean up +You'll want to remove the Jekyll configuration at this point. If you have anything else that isn't used, delete it. + +## A pratical example in a diff +[Hey, it's Alex](http://heyitsalex.net) was migrated in less than a _father-with-kids day_ from Jekyll to Hugo. You can see all the changes (and screw-ups) by looking at this [diff](https://github.com/alexandre-normand/alexandre-normand/compare/869d69435bd2665c3fbf5b5c78d4c22759d7613a...b7f6605b1265e83b4b81495423294208cc74d610). -- cgit v1.3