Compare commits

...

4 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 1726e90201 docs: Add Netlify badge if on Netlify 2017-04-16 11:09:50 +02:00
Bjørn Erik Pedersen 9cd6f69bdd Bump version to 0.20.2 2017-04-16 11:08:35 +02:00
Bjørn Erik Pedersen 68384622bb docs: Add 0.20.2 release notes 2017-04-16 11:05:00 +02:00
Bjørn Erik Pedersen 5f600fdd9f tplimpl: Allow text partials in HTML templates
Most obvius benefit of this is to include CSS partials with css file suffix into HTML templates.

A valid workaround would be to rename the file `mystyles.html`, but that doesn't work too good for external editors etc.

The css partial is  a method used in some themes before Hugo 0.20, but then it stopped working.

This commit reintroduces that behaviour.

Note that the regular layout lookups for text templates, i.e. "single.json" will be
prefixed with "_text/" on lookup and will only match in the text collection.

Fixes #3273
2017-04-16 11:04:52 +02:00
9 changed files with 91 additions and 36 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ pluralizeListTitles = false
[params]
description = "Documentation of Hugo, a fast and flexible static site generator built with love by spf13, bep and friends in Go"
author = "Steve Francia (spf13) and friends"
release = "0.20.1"
release = "0.20.2"
[taxonomies]
tag = "tags"
+46
View File
@@ -9,6 +9,52 @@ menu:
title: Release Notes
weight: 10
---
# **0.20.2** April 16th 2017
Hugo `0.20.2` adds support for plain text partials included into `HTML` templates. This was a side-effect of the big new [Custom Output Format](https://gohugo.io/extras/output-formats/) feature in `0.20`, and while the change was intentional and there was an ongoing discussion about fixing it in {{< gh 3273 >}}, it did break some themes. There were valid workarounds for these themes, but we might as well get it right.
The most obvious use case for this is inline `CSS` styles, which you now can do without having to name your partials with a `html` suffix.
A simple example:
In `layouts/partials/mystyles.css`:
```css
body {
background-color: {{ .Param "colors.main" }}
}
```
Then in `config.toml` (note that by using the `.Param` lookup func, we can override the color in a page's front matter if we want):
```toml
[params]
[params.colors]
main = "green"
text = "blue"
```
And then in `layouts/partials/head.html` (or the partial used to include the head section into your layout):
```html
<head>
<style type="text/css">
{{ partial "mystyles.css" . | safeCSS }}
</style>
</head>
```
Of course, `0.20` also made it super-easy to create external `CSS` stylesheets based on your site and page configuration. A simple example:
Add "CSS" to your home page's `outputs` list, create the template `/layouts/index.css` using Go template syntax for the dynamic parts, and then include it into your `HTML` template with:
```html
{{ with .OutputFormats.Get "css" }}
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
{{ end }}`
```
# **0.20.1** April 13th 2017
Hugo `0.20.1` is a bug fix release, fixing some important regressions introduced in `0.20` a couple of days ago:
+5
View File
@@ -3,6 +3,11 @@
<p>Last revision: {{ .Lastmod.Format "January 2, 2006" }}{{ if .IsPage }}{{ with .GitInfo }} | <a href="https://github.com/spf13/hugo/commit/{{ .Hash }}">{{ .Subject }} ({{ .AbbreviatedHash }})</a>{{end }}{{ end }}
<span style="float: right;">Hugo v{{ .Site.Params.release }} documentation</span>
</p>
{{ with getenv "REPOSITORY_URL" -}}
<a href="https://www.netlify.com" style="float: right; padding-right: 20px;">
<img src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"/>
</a>
{{- end }}
</div>
</div>
+1 -1
View File
@@ -27,7 +27,7 @@ const (
HugoVersionNumber = 0.20
// Increment this for bug releases
HugoPatchVersion = 1
HugoPatchVersion = 2
)
// HugoVersionSuffix is the suffix used in the Hugo version string.
+1 -1
View File
@@ -1,5 +1,5 @@
name: hugo
version: "0.20.1"
version: "0.20.2"
summary: Fast and Flexible Static Site Generator
description: |
Hugo is a static HTML and CSS website generator written in Go. It is
+11 -12
View File
@@ -97,23 +97,21 @@ func (t *templateHandler) PrintErrors() {
// Lookup tries to find a template with the given name in both template
// collections: First HTML, then the plain text template collection.
func (t *templateHandler) Lookup(name string) *tpl.TemplateAdapter {
var te *tpl.TemplateAdapter
isTextTemplate := strings.HasPrefix(name, textTmplNamePrefix)
if isTextTemplate {
if strings.HasPrefix(name, textTmplNamePrefix) {
// The caller has explicitly asked for a text template, so only look
// in the text template collection.
// The templates are stored without the prefix identificator.
name = strings.TrimPrefix(name, textTmplNamePrefix)
te = t.text.Lookup(name)
} else {
te = t.html.Lookup(name)
return t.text.Lookup(name)
}
if te == nil {
return nil
// Look in both
if te := t.html.Lookup(name); te != nil {
return te
}
return te
return t.text.Lookup(name)
}
func (t *templateHandler) clone(d *deps.Deps) *templateHandler {
@@ -459,9 +457,10 @@ func (t *templateHandler) loadTemplates(absPath string, prefix string) {
func (t *templateHandler) initFuncs() {
// The template funcs need separation between text and html templates.
// Both template types will get their own funcster instance, which
// in the current case contains the same set of funcs.
for _, funcsterHolder := range []templateFuncsterTemplater{t.html, t.text} {
funcster := newTemplateFuncster(t.Deps, funcsterHolder)
funcster := newTemplateFuncster(t.Deps)
// The URL funcs in the funcMap is somewhat language dependent,
// so we need to wait until the language and site config is loaded.
+6 -12
View File
@@ -17,6 +17,7 @@ import (
"fmt"
"html/template"
"strings"
texttemplate "text/template"
bp "github.com/spf13/hugo/bufferpool"
@@ -31,17 +32,12 @@ type templateFuncster struct {
cachedPartials partialCache
image *imageHandler
// Make sure each funcster gets its own TemplateFinder to get
// proper text and HTML template separation.
Tmpl templateFuncsterTemplater
*deps.Deps
}
func newTemplateFuncster(deps *deps.Deps, t templateFuncsterTemplater) *templateFuncster {
func newTemplateFuncster(deps *deps.Deps) *templateFuncster {
return &templateFuncster{
Deps: deps,
Tmpl: t,
cachedPartials: partialCache{p: make(map[string]interface{})},
image: &imageHandler{fs: deps.Fs, imageConfigCache: map[string]image.Config{}},
}
@@ -75,14 +71,12 @@ func (t *templateFuncster) partial(name string, contextList ...interface{}) (int
return "", err
}
switch t.Tmpl.(type) {
case *htmlTemplates:
return template.HTML(b.String()), nil
case *textTemplates:
if _, ok := templ.Template.(*texttemplate.Template); ok {
return b.String(), nil
default:
panic("Unknown type")
}
return template.HTML(b.String()), nil
}
}
+1 -1
View File
@@ -2221,5 +2221,5 @@ func (t *templateFuncster) initFuncMap() {
}
t.funcMap = funcMap
t.Tmpl.setFuncs(funcMap)
t.Tmpl.(*templateHandler).setFuncs(funcMap)
}
+19 -8
View File
@@ -2869,20 +2869,27 @@ func TestPartialHTMLAndText(t *testing.T) {
}
config.WithTemplate = func(templ tpl.TemplateHandler) error {
if err := templ.AddTemplate("htmlTemplate.html", `HTML Test Partial: {{ partial "test.foo" . -}}`); err != nil {
if err := templ.AddTemplate("htmlTemplate.html", `HTML Test|HTML:{{ partial "test.html" . -}}|Text:{{ partial "test.txt" . }}
CSS plain: <style type="text/css">{{ partial "mystyles.css" . -}}</style>
CSS safe: <style type="text/css">{{ partial "mystyles.css" . | safeCSS -}}</style>
`); err != nil {
return err
}
if err := templ.AddTemplate("_text/textTemplate.txt", `Text Test Partial: {{ partial "test.foo" . -}}`); err != nil {
if err := templ.AddTemplate("_text/textTemplate.txt", `Text Test|HTML:{{ partial "test.html" . -}}|Text:{{ partial "test.txt" . }}
CSS plain: <style type="text/css">{{ partial "mystyles.css" . -}}</style>`); err != nil {
return err
}
// Use "foo" here to say that the extension doesn't really matter in this scenario.
// It will look for templates in "partials/test.foo" and "partials/test.foo.html".
if err := templ.AddTemplate("partials/test.foo", "HTML Name: {{ .Name }}"); err != nil {
if err := templ.AddTemplate("partials/test.html", "HTML Name: {{ .Name }}"); err != nil {
return err
}
if err := templ.AddTemplate("_text/partials/test.foo", "Text Name: {{ .Name }}"); err != nil {
if err := templ.AddTemplate("_text/partials/test.txt", "Text Name: {{ .Name }}"); err != nil {
return err
}
if err := templ.AddTemplate("_text/partials/mystyles.css",
`body { background-color: blue; }
`); err != nil {
return err
}
@@ -2903,8 +2910,12 @@ func TestPartialHTMLAndText(t *testing.T) {
resultText, err := templ.ExecuteToString(data)
require.NoError(t, err)
require.Contains(t, resultHTML, "HTML Test Partial: HTML Name: a&#43;b&#43;c")
require.Contains(t, resultText, "Text Test Partial: Text Name: a+b+c")
require.Contains(t, resultHTML, "HTML Test|HTML:HTML Name: a&#43;b&#43;c|Text:Text Name: a&#43;b&#43;c")
require.Contains(t, resultHTML, `CSS plain: <style type="text/css">ZgotmplZ</style>`)
require.Contains(t, resultHTML, `CSS safe: <style type="text/css">body { background-color: blue; }`)
require.Contains(t, resultText, "Text Test|HTML:HTML Name: a&#43;b&#43;c|Text:Text Name: a+b+c")
require.Contains(t, resultText, `CSS plain: <style type="text/css">body { background-color: blue; }`)
}