diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-06-12 07:38:41 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-06-12 07:38:41 +0200 |
commit | c74b0f8f9b30866e09efac8235cc5e0093ab3d50 (patch) | |
tree | eb659a70bf4a7c54d956c8ddbae123680764e294 | |
parent | 80949dc73f0f728de6533798623d3e5fa386d7e0 (diff) |
docs: Update theme documentation
See #4460
-rw-r--r-- | docs/content/en/content-management/multilingual.md | 2 | ||||
-rw-r--r-- | docs/content/en/templates/lookup-order.md | 9 | ||||
-rw-r--r-- | docs/content/en/themes/creating.md | 61 | ||||
-rw-r--r-- | docs/content/en/themes/customizing.md | 80 | ||||
-rw-r--r-- | docs/content/en/themes/theme-components.md | 51 | ||||
-rw-r--r-- | docs/data/docs.json | 159 | ||||
-rw-r--r-- | output/docshelper.go | 55 |
7 files changed, 163 insertions, 254 deletions
diff --git a/docs/content/en/content-management/multilingual.md b/docs/content/en/content-management/multilingual.md index 9ac2efee7..34dafaa30 100644 --- a/docs/content/en/content-management/multilingual.md +++ b/docs/content/en/content-management/multilingual.md @@ -366,7 +366,7 @@ For merging of content from other languages (i.e. missing content translations), To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria: -* Come from the built-in `.Permalink` or `.URL` +* Come from the built-in `.Permalink` or `.RelPermalink` * Be constructed with * The [`relLangURL` template function][rellangurl] or the [`absLangURL` template function][abslangurl] **OR** * Prefixed with `{{ .LanguagePrefix }}` diff --git a/docs/content/en/templates/lookup-order.md b/docs/content/en/templates/lookup-order.md index d197b6141..343058e2d 100644 --- a/docs/content/en/templates/lookup-order.md +++ b/docs/content/en/templates/lookup-order.md @@ -58,14 +58,7 @@ Section ## Hugo Layouts Lookup Rules With Theme -In Hugo, layouts can live in either the project's or theme's layout folder, and the most specific layout will be chosen. Hugo will interleave the lookups: - - -1. layouts/page/index.html -2. demoTheme/layouts/page/index.html -3. layouts/... - -This way it is possible to override specific templates from the theme. +In Hugo, layouts can live in either the project's or the themes' layout folders, and the most specific layout will be chosen. Hugo will interleave the lookups listed below, finding the most specific one either in the project or themes. ## Examples: Layout Lookup for Regular Pages diff --git a/docs/content/en/themes/creating.md b/docs/content/en/themes/creating.md index a62f7c71b..1c1efc187 100644 --- a/docs/content/en/themes/creating.md +++ b/docs/content/en/themes/creating.md @@ -29,59 +29,44 @@ Hugo can initialize a new blank theme directory within your existing `themes` us hugo new theme [name] ``` -## Theme Components +## Theme Folders -A theme consists of templates and static assets such as javascript and css files. Themes can also provide [archetypes][], which are archetypal content types used by the `hugo new` command to scaffold new content files with preconfigured front matter. +A theme component can provide files in one or more of the following standard Hugo folders: +layouts +: Templates used to render content in Hugo. Also see [Templates Lookup Order](/templates/lookup-order/). -{{% note "Use the Hugo Generator Tag" %}} -The [`.Hugo.Generator`](/variables/hugo/) tag is included in all themes featured in the [Hugo Themes Showcase](http://themes.gohugo.io). We ask that you include the generator tag in all sites and themes you create with Hugo to help the core team track Hugo's usage and popularity. -{{% /note %}} +static +: Static files, such as logos, CSS and JavaScript. -## Layouts +i18n +: Language bundles. -Hugo is built around the concept that things should be as simple as possible. -Fundamentally, website content is displayed in two different ways, a single -piece of content and a list of content items. With Hugo, a theme layout starts -with the defaults. As additional layouts are defined, they are used for the -content type or section they apply to. This keeps layouts simple, but permits -a large amount of flexibility. +data +: Data files. -## Single Content +archetypes +: Content templates used in `hugo new`. -The default single file layout is located at `layouts/_default/single.html`. -## List of Contents +## Theme Configuration File -The default list file layout is located at `layouts/_default/list.html`. +A theme component can also provide its own [Configuration File](/getting-started/configuration/), e.g. `config.toml`. There are some restrictions to what can be configured in a theme component, and it is not possible to overwrite settings in the project. -## Partial Templates +The following settings can be set: -Theme creators should liberally use [partial templates](/templates/partials/) -throughout their theme files. Not only is a good DRY practice to include shared -code, but partials are a special template type that enables the themes end user -to be able to overwrite just a small piece of a file or inject code into the -theme from their local /layouts. These partial templates are perfect for easy -injection into the theme with minimal maintenance to ensure future -compatibility. +* `params` (global and per language) +* `menu` (global and per language) +* `outputformats` and `mediatypes` -## Static -Everything in the static directory will be copied directly into the final site -when rendered. No structure is provided here to enable complete freedom. It is -common to organize the static content into: +## Theme Description File -``` -/css -/js -/img -``` +In addition to the configuration file, a theme can also provide a `theme.toml` file that describes the theme, the author and origin etc. See [Add Your Hugo Theme to the Showcase](/contribute/themes/). -The actual structure is entirely up to you, the theme creator, on how you would like to organize your files. -## Archetypes +{{% note "Use the Hugo Generator Tag" %}} +The [`.Hugo.Generator`](/variables/hugo/) tag is included in all themes featured in the [Hugo Themes Showcase](http://themes.gohugo.io). We ask that you include the generator tag in all sites and themes you create with Hugo to help the core team track Hugo's usage and popularity. +{{% /note %}} -If your theme makes use of specific keys in the front matter, it is a good idea -to provide an archetype for each content type you have. [Read more about archetypes][archetypes]. -[archetypes]: /content-management/archetypes/ diff --git a/docs/content/en/themes/customizing.md b/docs/content/en/themes/customizing.md deleted file mode 100644 index 3444880f2..000000000 --- a/docs/content/en/themes/customizing.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Customize a Theme -linktitle: Customize a Theme -description: Customize a theme by overriding theme layouts and static assets in your top-level project directories. -date: 2017-02-01 -publishdate: 2017-02-01 -lastmod: 2017-02-01 -categories: [themes] -keywords: [themes, source, organization, directories] -menu: - docs: - parent: "themes" - weight: 20 -weight: 20 -sections_weight: 20 -draft: false -aliases: [/themes/customize/] -toc: true -wip: true ---- - -The following are key concepts for Hugo site customization with themes. Hugo permits you to supplement *or* override any theme template or static file with files in your working directory. - -{{% note %}} -When you use a theme cloned from its git repository, do not edit the theme's files directly. Instead, theme customization in Hugo is a matter of *overriding* the templates made available to you in a theme. This provides the added flexibility of tweaking a theme to meet your needs while staying current with a theme's upstream. -{{% /note %}} - -## Override Static Files - -There are times where you want to include static assets that differ from versions of the same asset that ships with a theme. - -For example, a theme may use jQuery 1.8 in the following location: - -``` -/themes/<THEME>/static/js/jquery.min.js -``` - -You want to replace the version of jQuery that ships with the theme with the newer `jquery-3.1.1.js`. The easiest way to do this is to replace the file *with a file of the same name* in the same relative path in your project's root. Therefore, change `jquery-3.1.1.js` to `jquery.min.js` so that it is *identical* to the theme's version and place the file here: - -``` -/static/js/jquery.min.js -``` - -## Override Template Files - -Anytime Hugo looks for a matching template, it will first check the working directory before looking in the theme directory. If you would like to modify a template, simply create that template in your local `layouts` directory. - -The [template lookup order][lookup] explains the rules Hugo uses to determine which template to use for a given piece of content. Read and understand these rules carefully. - -This is especially helpful when the theme creator used [partial templates][partials]. These partial templates are perfect for easy injection into the theme with minimal maintenance to ensure future compatibility. - -For example: - -``` -/themes/<THEME>/layouts/_default/single.html -``` - -Would be overwritten by - -``` -/layouts/_default/single.html -``` - -{{% warning %}} -This only works for templates that Hugo "knows about" (i.e., that follow its convention for folder structure and naming). If a theme imports template files in a creatively named directory, Hugo won’t know to look for the local `/layouts` first. -{{% /warning %}} - -## Override Archetypes - -If the archetype that ships with the theme for a given content type (or all content types) doesn’t fit with how you are using the theme, feel free to copy it to your `/archetypes` directory and make modifications as you see fit. - -{{% warning "Beware of `layouts/_default`" %}} -The `_default` directory is a very powerful force in Hugo, especially as it pertains to overwriting theme files. If a default file is located in the local [archetypes](/content-management/archetypes/) or layout directory (i.e., `archetypes/default.md` or `/layouts/_default/*.html`, respectively), it will override the file of the same name in the corresponding theme directory (i.e., `themes/<THEME>/archetypes/default.md` or `themes/<THEME>/layout/_defaults/*.html`, respectively). - -It is usually better to override specific files; i.e. rather than using `layouts/_default/*.html` in your working directory. -{{% /warning %}} - -[archetypes]: /content-management/archetypes/ -[lookup]: /templates/lookup-order/ -[partials]: /templates/partials/
\ No newline at end of file diff --git a/docs/content/en/themes/theme-components.md b/docs/content/en/themes/theme-components.md new file mode 100644 index 000000000..23312db31 --- /dev/null +++ b/docs/content/en/themes/theme-components.md @@ -0,0 +1,51 @@ +--- +title: Theme Components +linktitle: Theme Components +description: Hugo provides advanced theming support with Theme Components. +date: 2017-02-01 +categories: [themes] +keywords: [themes, theme, source, organization, directories] +menu: + docs: + parent: "themes" + weight: 20 +weight: 20 +sections_weight: 20 +draft: false +aliases: [/themes/customize/,/themes/customizing/] +toc: true +--- + +Since Hugo `0.42` a project can configure a theme as a composite of as many theme components you need: + +{{< code-toggle file="config">}} +theme = ["my-shortcodes", "base-theme", "hyde"] +{{< /code-toggle >}} + + +You can even nest this, and have the theme component itself include theme components in its own `config.toml` (theme inheritance).[^1] + +The theme definition example above in `config.toml` creates a theme with 3 theme components with presedence from left to right. + +So, Hugo will, for any given file, data entry etc., look first in the project, and then in `my-shortcode`, `base-theme` and lastly `hyde`. + +Hugo uses two different algorithms to merge the filesystems, depending on the file type: + +* For `i18n` and `data` files, Hugo merges deeply using the translation id and data key inside the files. +* For `static`, `layouts` (templates) and `archetypes` files, these are merged on file level. So the left-most file will be chosen. + +The name used in the `theme` definition above must match a folder in `/your-site/themes`, e.g. `/your-site/themes/my-shortcodes`. There are plans to improve on this and get a URL scheme so this can be resolved automatically. + +Also note that a component that is part of a theme can have its own configuration file, e.g. `config.toml`. There are currently some restrictions to what a theme component can configure: + +* `params` (global and per language) +* `menu` (global and per language) +* `outputformats` and `mediatypes` + +The same rules apply here: The left-most param/menu etc. with the same ID will win. There are some hidden and experimental namespace support in the above, which we will work to improve in the future, but theme authors are encouraged to create their own namespaces to avoid naming conflicts. + + +[^1]: Including theme components in the themes is currently not supported for themes hosted on [The Hugo Themes Site](https://themes.gohugo.io/), but can be really useful if you want to create your own theme based on a theme you find on that site. + + + diff --git a/docs/data/docs.json b/docs/data/docs.json index 3020a21f2..3ed3ab232 100644 --- a/docs/data/docs.json +++ b/docs/data/docs.json @@ -1188,6 +1188,15 @@ ] }, { + "Name": "plaintext", + "Aliases": [ + "no-highlight", + "plain", + "text", + "txt" + ] + }, + { "Name": "reStructuredText", "Aliases": [ "rest", @@ -1508,22 +1517,6 @@ ] }, { - "Example": "Single page in \"posts\" section with theme", - "Kind": "page", - "OutputFormat": "HTML", - "Suffix": "html", - "Template Lookup Order": [ - "layouts/posts/single.html.html", - "demoTheme/layouts/posts/single.html.html", - "layouts/posts/single.html", - "demoTheme/layouts/posts/single.html", - "layouts/_default/single.html.html", - "demoTheme/layouts/_default/single.html.html", - "layouts/_default/single.html", - "demoTheme/layouts/_default/single.html" - ] - }, - { "Example": "AMP single page", "Kind": "page", "OutputFormat": "AMP", @@ -1622,38 +1615,6 @@ ] }, { - "Example": "Home page with theme", - "Kind": "home", - "OutputFormat": "HTML", - "Suffix": "html", - "Template Lookup Order": [ - "layouts/index.html.html", - "demoTheme/layouts/index.html.html", - "layouts/home.html.html", - "demoTheme/layouts/home.html.html", - "layouts/list.html.html", - "demoTheme/layouts/list.html.html", - "layouts/index.html", - "demoTheme/layouts/index.html", - "layouts/home.html", - "demoTheme/layouts/home.html", - "layouts/list.html", - "demoTheme/layouts/list.html", - "layouts/_default/index.html.html", - "demoTheme/layouts/_default/index.html.html", - "layouts/_default/home.html.html", - "demoTheme/layouts/_default/home.html.html", - "layouts/_default/list.html.html", - "demoTheme/layouts/_default/list.html.html", - "layouts/_default/index.html", - "demoTheme/layouts/_default/index.html", - "layouts/_default/home.html", - "demoTheme/layouts/_default/home.html", - "layouts/_default/list.html", - "demoTheme/layouts/_default/list.html" - ] - }, - { "Example": "AMP home, French language\"", "Kind": "home", "OutputFormat": "AMP", @@ -1706,39 +1667,25 @@ ] }, { - "Example": "RSS home with theme", + "Example": "RSS home", "Kind": "home", "OutputFormat": "RSS", "Suffix": "xml", "Template Lookup Order": [ "layouts/index.rss.xml", - "demoTheme/layouts/index.rss.xml", "layouts/home.rss.xml", - "demoTheme/layouts/home.rss.xml", "layouts/rss.xml", - "demoTheme/layouts/rss.xml", "layouts/list.rss.xml", - "demoTheme/layouts/list.rss.xml", "layouts/index.xml", - "demoTheme/layouts/index.xml", "layouts/home.xml", - "demoTheme/layouts/home.xml", "layouts/list.xml", - "demoTheme/layouts/list.xml", "layouts/_default/index.rss.xml", - "demoTheme/layouts/_default/index.rss.xml", "layouts/_default/home.rss.xml", - "demoTheme/layouts/_default/home.rss.xml", "layouts/_default/rss.xml", - "demoTheme/layouts/_default/rss.xml", "layouts/_default/list.rss.xml", - "demoTheme/layouts/_default/list.rss.xml", "layouts/_default/index.xml", - "demoTheme/layouts/_default/index.xml", "layouts/_default/home.xml", - "demoTheme/layouts/_default/home.xml", "layouts/_default/list.xml", - "demoTheme/layouts/_default/list.xml", "layouts/_internal/_default/rss.xml" ] }, @@ -2978,6 +2925,24 @@ } }, "path": { + "Base": { + "Description": "", + "Args": null, + "Aliases": null, + "Examples": null + }, + "Dir": { + "Description": "", + "Args": null, + "Aliases": null, + "Examples": null + }, + "Ext": { + "Description": "", + "Args": null, + "Aliases": null, + "Examples": null + }, "Join": { "Description": "Join joins any number of path elements into a single path, adding a\nseparating slash if necessary. All the input\npath elements are passed into filepath.ToSlash converting any Windows slashes\nto forward slashes.\nThe result is Cleaned; in particular,\nall empty strings are ignored.", "Args": [ @@ -2992,6 +2957,18 @@ [ "{{ path.Join \"my\" \"path\" \"filename.txt\" }}", "my/path/filename.txt" + ], + [ + "{{ \"my/path/filename.txt\" | path.Ext }}", + ".txt" + ], + [ + "{{ \"my/path/filename.txt\" | path.Base }}", + "filename.txt" + ], + [ + "{{ \"my/path/filename.txt\" | path.Dir }}", + "my/path" ] ] }, @@ -3146,25 +3123,7 @@ "Aliases": [ "countrunes" ], - "Examples": [ - [ - "{{ \"Hello, 世界\" | countrunes }}", - "8" - ] - ] - }, - "RuneCount": { - "Description": "RuneCount returns the number of runes in s", - "Args": [ - "s" - ], - "Aliases": [], - "Examples": [ - [ - "{{ \"Hello, 世界\" | strings.RuneCount }}", - "9" - ] - ] + "Examples": [] }, "CountWords": { "Description": "CountWords returns the approximate word count in s.", @@ -3219,6 +3178,20 @@ "Aliases": null, "Examples": null }, + "Repeat": { + "Description": "Repeat returns a new string consisting of count copies of the string s.", + "Args": [ + "n", + "s" + ], + "Aliases": null, + "Examples": [ + [ + "{{ \"yo\" | strings.Repeat 4 }}", + "yoyoyoyo" + ] + ] + }, "Replace": { "Description": "Replace returns a copy of the string s with all occurrences of old replaced\nwith new.", "Args": [ @@ -3248,6 +3221,14 @@ ], "Examples": [] }, + "RuneCount": { + "Description": "RuneCount returns the number of runes in s.", + "Args": [ + "s" + ], + "Aliases": null, + "Examples": [] + }, "SliceString": { "Description": "SliceString slices a string by specifying a half-open range with\ntwo indices, start and end. 1 and 4 creates a slice including elements 1 through 3.\nThe end index can be omitted, it defaults to the string's length.", "Args": [ @@ -3428,20 +3409,6 @@ ] ] }, - "Repeat": { - "Description": "Repeat returns a new string consisting of count copies of the string s.", - "Args": [ - "s", - "n" - ], - "Aliases": null, - "Examples": [ - [ - "{{ \"yo\" | strings.Repeat 4 }}", - "yoyoyoyo" - ] - ] - }, "Truncate": { "Description": "Truncate truncates a given string to the specified length.", "Args": [ diff --git a/output/docshelper.go b/output/docshelper.go index fcf9ae61c..4c724b020 100644 --- a/output/docshelper.go +++ b/output/docshelper.go @@ -38,34 +38,31 @@ func createLayoutExamples() interface{} { ) for _, example := range []struct { - name string - d LayoutDescriptor - hasTheme bool - f Format + name string + d LayoutDescriptor + f Format }{ // Taxonomy output.LayoutDescriptor={categories category taxonomy en false Type Section - {"Single page in \"posts\" section", LayoutDescriptor{Kind: "page", Type: "posts"}, false, HTMLFormat}, - {"Single page in \"posts\" section with layout set", LayoutDescriptor{Kind: "page", Type: "posts", Layout: demoLayout}, false, HTMLFormat}, - {"Single page in \"posts\" section with theme", LayoutDescriptor{Kind: "page", Type: "posts"}, true, HTMLFormat}, - {"AMP single page", LayoutDescriptor{Kind: "page", Type: "posts"}, false, AMPFormat}, - {"AMP single page, French language", LayoutDescriptor{Kind: "page", Type: "posts", Lang: "fr"}, false, AMPFormat}, + {"Single page in \"posts\" section", LayoutDescriptor{Kind: "page", Type: "posts"}, HTMLFormat}, + {"Single page in \"posts\" section with layout set", LayoutDescriptor{Kind: "page", Type: "posts", Layout: demoLayout}, HTMLFormat}, + {"AMP single page", LayoutDescriptor{Kind: "page", Type: "posts"}, AMPFormat}, + {"AMP single page, French language", LayoutDescriptor{Kind: "page", Type: "posts", Lang: "fr"}, AMPFormat}, // All section or typeless pages gets "page" as type - {"Home page", LayoutDescriptor{Kind: "home", Type: "page"}, false, HTMLFormat}, - {"Home page with type set", LayoutDescriptor{Kind: "home", Type: demoType}, false, HTMLFormat}, - {"Home page with layout set", LayoutDescriptor{Kind: "home", Type: "page", Layout: demoLayout}, false, HTMLFormat}, - {`Home page with theme`, LayoutDescriptor{Kind: "home", Type: "page"}, true, HTMLFormat}, - {`AMP home, French language"`, LayoutDescriptor{Kind: "home", Type: "page", Lang: "fr"}, false, AMPFormat}, - {"JSON home", LayoutDescriptor{Kind: "home", Type: "page"}, false, JSONFormat}, - {"RSS home with theme", LayoutDescriptor{Kind: "home", Type: "page"}, true, RSSFormat}, - {"RSS section posts", LayoutDescriptor{Kind: "section", Type: "posts"}, false, RSSFormat}, - {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, false, RSSFormat}, - {"Taxonomy terms in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, false, RSSFormat}, - {"Section list for \"posts\" section", LayoutDescriptor{Kind: "section", Type: "posts", Section: "posts"}, false, HTMLFormat}, - {"Section list for \"posts\" section with type set to \"blog\"", LayoutDescriptor{Kind: "section", Type: "blog", Section: "posts"}, false, HTMLFormat}, - {"Section list for \"posts\" section with layout set to \"demoLayout\"", LayoutDescriptor{Kind: "section", Layout: demoLayout, Section: "posts"}, false, HTMLFormat}, - - {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, false, HTMLFormat}, - {"Taxonomy term in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, false, HTMLFormat}, + {"Home page", LayoutDescriptor{Kind: "home", Type: "page"}, HTMLFormat}, + {"Home page with type set", LayoutDescriptor{Kind: "home", Type: demoType}, HTMLFormat}, + {"Home page with layout set", LayoutDescriptor{Kind: "home", Type: "page", Layout: demoLayout}, HTMLFormat}, + {`AMP home, French language"`, LayoutDescriptor{Kind: "home", Type: "page", Lang: "fr"}, AMPFormat}, + {"JSON home", LayoutDescriptor{Kind: "home", Type: "page"}, JSONFormat}, + {"RSS home", LayoutDescriptor{Kind: "home", Type: "page"}, RSSFormat}, + {"RSS section posts", LayoutDescriptor{Kind: "section", Type: "posts"}, RSSFormat}, + {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, RSSFormat}, + {"Taxonomy terms in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, RSSFormat}, + {"Section list for \"posts\" section", LayoutDescriptor{Kind: "section", Type: "posts", Section: "posts"}, HTMLFormat}, + {"Section list for \"posts\" section with type set to \"blog\"", LayoutDescriptor{Kind: "section", Type: "blog", Section: "posts"}, HTMLFormat}, + {"Section list for \"posts\" section with layout set to \"demoLayout\"", LayoutDescriptor{Kind: "section", Layout: demoLayout, Section: "posts"}, HTMLFormat}, + + {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, HTMLFormat}, + {"Taxonomy term in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, HTMLFormat}, } { l := NewLayoutHandler() @@ -90,12 +87,8 @@ func makeLayoutsPresentable(l []string) []string { // This is a valid lookup, but it's more confusing than useful. continue } - ll = strings.TrimPrefix(ll, "_text/") - if strings.Contains(ll, "theme/") { - ll = strings.Replace(ll, "theme/", "demoTheme/layouts/", -1) - } else { - ll = "layouts/" + ll - } + ll = "layouts/" + strings.TrimPrefix(ll, "_text/") + if !strings.Contains(ll, "indexes") { filtered = append(filtered, ll) } |