2016-03-21 10:36:19 -04:00
// Copyright 2016 The Hugo Authors. All rights reserved.
2015-12-10 17:19:38 -05:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2014-02-25 23:57:31 -05:00
package hugolib
import (
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
"fmt"
2016-01-09 10:11:38 -05:00
"path/filepath"
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
"reflect"
"regexp"
"sort"
2014-02-25 23:57:31 -05:00
"strings"
"testing"
2014-11-20 12:32:21 -05:00
2017-05-06 14:15:28 -04:00
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/afero"
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/output"
2017-05-06 14:15:28 -04:00
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/media"
2017-05-06 14:15:28 -04:00
2017-06-13 12:42:45 -04:00
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/tpl"
2016-08-07 08:03:03 -04:00
"github.com/stretchr/testify/require"
2014-02-25 23:57:31 -05:00
)
2016-08-07 08:03:03 -04:00
// TODO(bep) remove
2017-03-27 14:43:49 -04:00
func pageFromString ( in , filename string , withTemplate ... func ( templ tpl . TemplateHandler ) error ) ( * Page , error ) {
2017-02-04 22:20:06 -05:00
s := newTestSite ( nil )
2017-01-09 19:36:59 -05:00
if len ( withTemplate ) > 0 {
// Have to create a new site
2017-01-10 04:55:03 -05:00
var err error
2017-02-04 22:20:06 -05:00
cfg , fs := newTestCfg ( )
2017-03-06 13:54:46 -05:00
d := deps . DepsCfg { Language : helpers . NewLanguage ( "en" , cfg ) , Cfg : cfg , Fs : fs , WithTemplate : withTemplate [ 0 ] }
2017-02-04 22:20:06 -05:00
s , err = NewSiteForCfg ( d )
2017-01-10 04:55:03 -05:00
if err != nil {
return nil , err
}
2017-01-09 19:36:59 -05:00
}
return s . NewPageFrom ( strings . NewReader ( in ) , filename )
2014-02-25 23:57:31 -05:00
}
2017-03-27 14:43:49 -04:00
func CheckShortCodeMatch ( t * testing . T , input , expected string , withTemplate func ( templ tpl . TemplateHandler ) error ) {
2016-08-07 08:03:03 -04:00
CheckShortCodeMatchAndError ( t , input , expected , withTemplate , false )
2015-08-07 14:08:23 -04:00
}
2017-03-27 14:43:49 -04:00
func CheckShortCodeMatchAndError ( t * testing . T , input , expected string , withTemplate func ( templ tpl . TemplateHandler ) error , expectError bool ) {
2014-02-25 23:57:31 -05:00
2017-02-04 22:20:06 -05:00
cfg , fs := newTestCfg ( )
2017-01-10 04:55:03 -05:00
2017-06-13 12:47:17 -04:00
// Need some front matter, see https://github.com/gohugoio/hugo/issues/2337
2016-08-07 08:03:03 -04:00
contentFile := ` -- -
title : "Title"
-- -
` + input
2017-01-10 04:55:03 -05:00
writeSource ( t , fs , "content/simple.md" , contentFile )
2016-08-07 08:03:03 -04:00
2017-02-04 22:20:06 -05:00
h , err := NewHugoSites ( deps . DepsCfg { Fs : fs , Cfg : cfg , WithTemplate : withTemplate } )
2016-08-07 08:03:03 -04:00
2017-01-10 04:55:03 -05:00
require . NoError ( t , err )
require . Len ( t , h . Sites , 1 )
2016-08-07 08:03:03 -04:00
2017-01-10 04:55:03 -05:00
err = h . Build ( BuildCfg { } )
2015-04-29 13:08:34 -04:00
2015-08-07 14:08:23 -04:00
if err != nil && ! expectError {
2016-08-07 08:03:03 -04:00
t . Fatalf ( "Shortcode rendered error %s." , err )
2015-04-29 13:08:34 -04:00
}
2014-02-25 23:57:31 -05:00
2015-08-07 14:08:23 -04:00
if err == nil && expectError {
t . Fatalf ( "No error from shortcode" )
}
2016-11-13 08:27:10 -05:00
require . Len ( t , h . Sites [ 0 ] . RegularPages , 1 )
2016-08-07 08:03:03 -04:00
2018-04-19 12:06:40 -04:00
output := strings . TrimSpace ( string ( h . Sites [ 0 ] . RegularPages [ 0 ] . content ( ) ) )
2016-11-23 12:28:14 -05:00
output = strings . TrimPrefix ( output , "<p>" )
output = strings . TrimSuffix ( output , "</p>" )
2016-08-07 08:03:03 -04:00
expected = strings . TrimSpace ( expected )
2014-02-25 23:57:31 -05:00
if output != expected {
2016-03-13 17:06:51 -04:00
t . Fatalf ( "Shortcode render didn't match. got \n%q but expected \n%q" , output , expected )
2014-02-25 23:57:31 -05:00
}
}
func TestNonSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
// notice the syntax diff from 0.12, now comment delims must be added
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , "{{%/* movie 47238zzb */%}}" , "{{% movie 47238zzb %}}" , nil )
2014-02-25 23:57:31 -05:00
}
2015-02-27 05:57:23 -05:00
// Issue #929
func TestHyphenatedSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/hyphenated-video.html" , ` Playing Video {{ .Get 0 }} ` )
2016-08-07 08:03:03 -04:00
return nil
}
2015-02-27 05:57:23 -05:00
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , "{{< hyphenated-video 47238zzb >}}" , "Playing Video 47238zzb" , wt )
2015-02-27 05:57:23 -05:00
}
2016-01-04 17:48:05 -05:00
// Issue #1753
func TestNoTrailingNewline ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/a.html" , ` {{ .Get 0 }} ` )
2016-08-07 08:03:03 -04:00
return nil
}
2016-01-04 17:48:05 -05:00
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , "ab{{< a c >}}d" , "abcd" , wt )
2016-01-04 17:48:05 -05:00
}
2014-02-25 23:57:31 -05:00
func TestPositionalParamSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/video.html" , ` Playing Video {{ .Get 0 }} ` )
2016-08-07 08:03:03 -04:00
return nil
}
2014-02-25 23:57:31 -05:00
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , "{{< video 47238zzb >}}" , "Playing Video 47238zzb" , wt )
CheckShortCodeMatch ( t , "{{< video 47238zzb 132 >}}" , "Playing Video 47238zzb" , wt )
CheckShortCodeMatch ( t , "{{<video 47238zzb>}}" , "Playing Video 47238zzb" , wt )
CheckShortCodeMatch ( t , "{{<video 47238zzb >}}" , "Playing Video 47238zzb" , wt )
CheckShortCodeMatch ( t , "{{< video 47238zzb >}}" , "Playing Video 47238zzb" , wt )
2014-02-25 23:57:31 -05:00
}
2015-08-07 13:21:26 -04:00
func TestPositionalParamIndexOutOfBounds ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
2018-04-17 05:29:00 -04:00
tem . AddTemplate ( "_internal/shortcodes/video.html" , ` Playing Video {{ with .Get 1 }} {{ . }} {{ else }} Missing {{ end }} ` )
2016-08-07 08:03:03 -04:00
return nil
}
2018-04-17 05:29:00 -04:00
CheckShortCodeMatch ( t , "{{< video 47238zzb >}}" , "Playing Video Missing" , wt )
2015-08-07 13:21:26 -04:00
}
2015-08-07 14:08:23 -04:00
// some repro issues for panics in Go Fuzz testing
2014-02-25 23:57:31 -05:00
func TestNamedParamSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/img.html" , ` <img {{ with .Get "src" }} src=" {{ . }} " {{ end }} {{ with .Get "class" }} class=" {{ . }} " {{ end }} > ` )
2016-08-07 08:03:03 -04:00
return nil
}
CheckShortCodeMatch ( t , ` {{ < img src = "one" > }} ` , ` <img src="one"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < img class = "aspen" > }} ` , ` <img class="aspen"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < img src = "one" > }} ` , ` <img src="one"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < img src = "one" > }} ` , ` <img src="one"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < img src = "one" > }} ` , ` <img src="one"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < img src = "one" class = "aspen grove" > }} ` , ` <img src="one" class="aspen grove"> ` , wt )
2014-02-25 23:57:31 -05:00
}
2016-07-21 11:18:55 -04:00
// Issue #2294
func TestNestedNamedMissingParam ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/acc.html" , ` <div class="acc"> {{ .Inner }} </div> ` )
tem . AddTemplate ( "_internal/shortcodes/div.html" , ` <div {{ with .Get "class" }} class=" {{ . }} " {{ end }} > {{ .Inner }} </div> ` )
tem . AddTemplate ( "_internal/shortcodes/div2.html" , ` <div {{ with .Get 0 }} class=" {{ . }} " {{ end }} > {{ .Inner }} </div> ` )
2016-08-07 08:03:03 -04:00
return nil
}
2016-07-21 11:18:55 -04:00
CheckShortCodeMatch ( t ,
2016-07-21 15:03:44 -04:00
` {{ % acc % }} {{ % div % }} d1 {{ % / div % }} {{ % div2 % }} d2 {{ % / div2 % }} {{ % / acc % }} ` ,
2016-08-07 08:03:03 -04:00
"<div class=\"acc\"><div >d1</div><div >d2</div>\n</div>" , wt )
2016-07-21 11:18:55 -04:00
}
2015-11-20 19:59:54 -05:00
func TestIsNamedParamsSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/byposition.html" , ` <div id=" {{ .Get 0 }} "> ` )
tem . AddTemplate ( "_internal/shortcodes/byname.html" , ` <div id=" {{ .Get "id" }} "> ` )
tem . AddTemplate ( "_internal/shortcodes/ifnamedparams.html" , ` <div id=" {{ if .IsNamedParams }} {{ .Get "id" }} {{ else }} {{ .Get 0 }} {{ end }} "> ` )
2016-08-07 08:03:03 -04:00
return nil
}
CheckShortCodeMatch ( t , ` {{ < ifnamedparams id = "name" > }} ` , ` <div id="name"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < ifnamedparams position > }} ` , ` <div id="position"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < byname id = "name" > }} ` , ` <div id="name"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < byname position > }} ` , ` <div id="error: cannot access positional params by string name"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < byposition position > }} ` , ` <div id="position"> ` , wt )
CheckShortCodeMatch ( t , ` {{ < byposition id = "name" > }} ` , ` <div id="error: cannot access named params by position"> ` , wt )
2015-11-20 19:59:54 -05:00
}
2014-02-25 23:57:31 -05:00
func TestInnerSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/inside.html" , ` <div {{ with .Get "class" }} class=" {{ . }} " {{ end }} > {{ .Inner }} </div> ` )
2016-08-07 08:03:03 -04:00
return nil
}
CheckShortCodeMatch ( t , ` {{ < inside class = "aspen" > }} ` , ` <div class="aspen"></div> ` , wt )
CheckShortCodeMatch ( t , ` {{ < inside class = "aspen" > }} More Here {{ < / inside > }} ` , "<div class=\"aspen\">More Here</div>" , wt )
CheckShortCodeMatch ( t , ` {{ < inside > }} More Here {{ < / inside > }} ` , "<div>More Here</div>" , wt )
2014-08-28 12:48:31 -04:00
}
func TestInnerSCWithMarkdown ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/inside.html" , ` <div {{ with .Get "class" }} class=" {{ . }} " {{ end }} > {{ .Inner }} </div> ` )
2016-08-07 08:03:03 -04:00
return nil
}
2014-08-28 12:48:31 -04:00
CheckShortCodeMatch ( t , ` { { % inside % } }
# More Here
[ link ] ( http : //spf13.com) and text
2016-08-07 08:03:03 -04:00
{ { % / inside % } } ` , "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>" , wt )
2014-02-25 23:57:31 -05:00
}
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
func TestInnerSCWithAndWithoutMarkdown ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/inside.html" , ` <div {{ with .Get "class" }} class=" {{ . }} " {{ end }} > {{ .Inner }} </div> ` )
2016-08-07 08:03:03 -04:00
return nil
}
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
CheckShortCodeMatch ( t , ` { { % inside % } }
# More Here
[ link ] ( http : //spf13.com) and text
{ { % / inside % } }
And then :
{ { < inside > } }
# More Here
This is * * plain * * text .
{ { < / inside > } }
2016-08-07 08:03:03 -04:00
` , "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>\n\n<p>And then:</p>\n\n<p><div>\n# More Here\n\nThis is **plain** text.\n\n</div>" , wt )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
2014-02-25 23:57:31 -05:00
func TestEmbeddedSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , "{{% test %}}" , "This is a simple Test" , nil )
CheckShortCodeMatch ( t , ` {{ % figure src = "/found/here" class = "bananas orange" % }} ` , "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" />\n \n \n</figure>\n" , nil )
CheckShortCodeMatch ( t , ` {{ % figure src = "/found/here" class = "bananas orange" caption = "This is a caption" % }} ` , "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"This is a caption\" />\n \n \n <figcaption>\n <p>\n This is a caption\n \n \n \n </p> \n </figcaption>\n \n</figure>\n" , nil )
2014-02-25 23:57:31 -05:00
}
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
func TestNestedSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/scn1.html" , ` <div>Outer, inner is {{ .Inner }} </div> ` )
tem . AddTemplate ( "_internal/shortcodes/scn2.html" , ` <div>SC2</div> ` )
2016-08-07 08:03:03 -04:00
return nil
}
CheckShortCodeMatch ( t , ` {{ % scn1 % }} {{ % scn2 % }} {{ % / scn1 % }} ` , "<div>Outer, inner is <div>SC2</div>\n</div>" , wt )
Provide (relative) reference funcs & shortcodes.
- `.Ref` and `.RelRef` take a reference (the logical filename for a
page, including extension and/or a document fragment ID) and return
a permalink (or relative permalink) to the referenced document.
- If the reference is a page name (such as `about.md`), the page
will be discovered and the permalink will be returned: `/about/`
- If the reference is a page name with a fragment (such as
`about.md#who`), the page will be discovered and used to add the
`page.UniqueID()` to the resulting fragment and permalink:
`/about/#who:deadbeef`.
- If the reference is a fragment and `.*Ref` has been called from
a `Node` or `SiteInfo`, it will be returned as is: `#who`.
- If the reference is a fragment and `.*Ref` has been called from
a `Page`, it will be returned with the page’s unique ID:
`#who:deadbeef`.
- `.*Ref` can be called from either `Node`, `SiteInfo` (e.g.,
`Node.Site`), `Page` objects, or `ShortcodeWithPage` objects in
templates.
- `.*Ref` cannot be used in content, so two shortcodes have been
created to provide the functionality to content: `ref` and `relref`.
These are intended to be used within markup, like `[Who]({{% ref
about.md#who %}})` or `<a href="{{% ref about.md#who %}}">Who</a>`.
- There are also `ref` and `relref` template functions (used to create
the shortcodes) that expect a `Page` or `Node` object and the
reference string (e.g., `{{ relref . "about.md" }}` or `{{
"about.md" | ref . }}`). It actually looks for `.*Ref` as defined on
`Node` or `Page` objects.
- Shortcode handling had to use a *differently unique* wrapper in
`createShortcodePlaceholder` because of the way that the `ref` and
`relref` are intended to be used in content.
2014-11-24 01:15:34 -05:00
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , ` {{ < scn1 > }} {{ % scn2 % }} {{ < / scn1 > }} ` , "<div>Outer, inner is <div>SC2</div></div>" , wt )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
func TestNestedComplexSC ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/row.html" , ` -row- {{ .Inner }} -rowStop- ` )
tem . AddTemplate ( "_internal/shortcodes/column.html" , ` -col- {{ .Inner }} -colStop- ` )
tem . AddTemplate ( "_internal/shortcodes/aside.html" , ` -aside- {{ .Inner }} -asideStop- ` )
2016-08-07 08:03:03 -04:00
return nil
}
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
CheckShortCodeMatch ( t , ` {{ < row > }} 1-s {{ % column % }} 2-**s** {{ < aside > }} 3-**s** {{ < / aside > }} 4-s {{ % / column % }} 5-s {{ < / row > }} 6-s ` ,
2016-08-07 08:03:03 -04:00
"-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s" , wt )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
// turn around the markup flag
CheckShortCodeMatch ( t , ` {{ % row % }} 1-s {{ < column > }} 2-**s** {{ % aside % }} 3-**s** {{ % / aside % }} 4-s {{ < / column > }} 5-s {{ % / row % }} 6-s ` ,
2016-08-07 08:03:03 -04:00
"-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s" , wt )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
2016-03-08 14:56:24 -05:00
func TestParentShortcode ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2017-03-27 14:43:49 -04:00
wt := func ( tem tpl . TemplateHandler ) error {
tem . AddTemplate ( "_internal/shortcodes/r1.html" , ` 1: {{ .Get "pr1" }} {{ .Inner }} ` )
tem . AddTemplate ( "_internal/shortcodes/r2.html" , ` 2: {{ .Parent .Get "pr1" }} {{ .Get "pr2" }} {{ .Inner }} ` )
tem . AddTemplate ( "_internal/shortcodes/r3.html" , ` 3: {{ .Parent .Parent .Get "pr1" }} {{ .Parent .Get "pr2" }} {{ .Get "pr3" }} {{ .Inner }} ` )
2016-08-07 08:03:03 -04:00
return nil
}
2016-03-08 14:56:24 -05:00
CheckShortCodeMatch ( t , ` {{ < r1 pr1 = "p1" > }} 1: {{ < r2 pr2 = "p2" > }} 2: {{ < r3 pr3 = "p3" > }} {{ < / r3 > }} {{ < / r2 > }} {{ < / r1 > }} ` ,
2016-08-07 08:03:03 -04:00
"1: p1 1: 2: p1p2 2: 3: p1p2p3 " , wt )
2016-03-08 14:56:24 -05:00
}
2018-02-05 14:06:29 -05:00
func TestFigureOnlySrc ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ < figure src = "/found/here" > }} ` , "\n<figure>\n \n <img src=\"/found/here\" />\n \n \n</figure>\n" , nil )
}
2014-10-08 10:54:50 -04:00
func TestFigureImgWidth ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2016-08-07 08:03:03 -04:00
CheckShortCodeMatch ( t , ` {{ % figure src = "/found/here" class = "bananas orange" alt = "apple" width = "100px" % }} ` , "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n \n \n</figure>\n" , nil )
2014-10-08 10:54:50 -04:00
}
2017-10-27 11:37:54 -04:00
func TestFigureImgHeight ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ % figure src = "/found/here" class = "bananas orange" alt = "apple" height = "100px" % }} ` , "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" height=\"100px\" />\n \n \n</figure>\n" , nil )
}
func TestFigureImgWidthAndHeight ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ % figure src = "/found/here" class = "bananas orange" alt = "apple" width = "50" height = "100" % }} ` , "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"50\" height=\"100\" />\n \n \n</figure>\n" , nil )
}
2018-02-05 14:06:29 -05:00
func TestFigureLinkNoTarget ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ < figure src = "/found/here" link = "/jump/here/on/clicking" > }} ` , "\n<figure>\n <a href=\"/jump/here/on/clicking\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n" , nil )
}
func TestFigureLinkWithTarget ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ < figure src = "/found/here" link = "/jump/here/on/clicking" target = "_self" > }} ` , "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_self\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n" , nil )
}
func TestFigureLinkWithTargetAndRel ( t * testing . T ) {
t . Parallel ( )
CheckShortCodeMatch ( t , ` {{ < figure src = "/found/here" link = "/jump/here/on/clicking" target = "_blank" rel = "noopener" > }} ` , "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_blank\" rel=\"noopener\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n" , nil )
}
2016-09-08 15:23:01 -04:00
const testScPlaceholderRegexp = "HAHAHUGOSHORTCODE-\\d+HBHB"
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
func TestExtractShortcodes ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
for i , this := range [ ] struct {
name string
input string
expectShortCodes string
expect interface { }
expectErrorMsg string
} {
{ "text" , "Some text." , "map[]" , "Some text." , "" } ,
2017-02-21 18:14:27 -05:00
{ "invalid right delim" , "{{< tag }}" , "" , false , "simple.md:4:.*unrecognized character.*}" } ,
{ "invalid close" , "\n{{< /tag >}}" , "" , false , "simple.md:5:.*got closing shortcode, but none is open" } ,
{ "invalid close2" , "\n\n{{< tag >}}{{< /anotherTag >}}" , "" , false , "simple.md:6: closing tag for shortcode 'anotherTag' does not match start tag" } ,
{ "unterminated quote 1" , ` {{ < figure src = "im caption=" S " > }} ` , "" , false , "simple.md:4:.got pos.*" } ,
{ "unterminated quote 1" , ` {{ < figure src = "im" caption = " S > }} ` , "" , false , "simple.md:4:.*unterm.*}" } ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
{ "one shortcode, no markup" , "{{< tag >}}" , "" , testScPlaceholderRegexp , "" } ,
{ "one shortcode, markup" , "{{% tag %}}" , "" , testScPlaceholderRegexp , "" } ,
{ "one pos param" , "{{% tag param1 %}}" , ` tag([\"param1\"], true) { []}"] ` , testScPlaceholderRegexp , "" } ,
{ "two pos params" , "{{< tag param1 param2>}}" , ` tag([\"param1\" \"param2\"], false) { []}"] ` , testScPlaceholderRegexp , "" } ,
2014-11-18 04:20:52 -05:00
{ "one named param" , ` {{ % tag param1 = "value" % }} ` , ` tag([\"param1:value\"], true) { []} ` , testScPlaceholderRegexp , "" } ,
{ "two named params" , ` {{ < tag param1 = "value1" param2 = "value2" > }} ` , ` tag([\"param1:value1\" \"param2:value2\"], false) { []}"] ` ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
testScPlaceholderRegexp , "" } ,
{ "inner" , ` Some text. {{ < inner > }} Inner Content {{ < / inner > }} . Some more text. ` , ` inner([], false) { [Inner Content]} ` ,
fmt . Sprintf ( "Some text. %s. Some more text." , testScPlaceholderRegexp ) , "" } ,
2015-03-02 15:23:16 -05:00
// issue #934
{ "inner self-closing" , ` Some text. {{ < inner / > }} . Some more text. ` , ` inner([], false) { []} ` ,
fmt . Sprintf ( "Some text. %s. Some more text." , testScPlaceholderRegexp ) , "" } ,
2015-02-28 13:24:30 -05:00
{ "close, but not inner" , "{{< tag >}}foo{{< /tag >}}" , "" , false , "Shortcode 'tag' in page 'simple.md' has no .Inner.*" } ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
{ "nested inner" , ` Inner-> {{ < inner > }} Inner Content-> {{ % inner2 param1 % }} inner2txt {{ % / inner2 % }} Inner close-> {{ < / inner > }} <-done ` ,
` inner([], false) { [Inner Content-> inner2([\"param1\"], true) { [inner2txt]} Inner close->]} ` ,
fmt . Sprintf ( "Inner->%s<-done" , testScPlaceholderRegexp ) , "" } ,
{ "nested, nested inner" , ` Inner-> {{ < inner > }} inner2-> {{ % inner2 param1 % }} inner2txt->inner3 {{ < inner3 > }} inner3txt {{ < / inner3 > }} {{ % / inner2 % }} final close-> {{ < / inner > }} <-done ` ,
` inner([], false) { [inner2-> inner2([\"param1\"], true) { [inner2txt->inner3 inner3(%!q(<nil>), false) { [inner3txt]}]} final close-> ` ,
fmt . Sprintf ( "Inner->%s<-done" , testScPlaceholderRegexp ) , "" } ,
{ "two inner" , ` Some text. {{ % inner % }} First **Inner** Content {{ % / inner % }} {{ < inner > }} Inner **Content** {{ < / inner > }} . Some more text. ` ,
2016-09-08 15:23:01 -04:00
` map["HAHAHUGOSHORTCODE-1HBHB:inner([], true) { [First **Inner** Content]}" "HAHAHUGOSHORTCODE-2HBHB:inner([], false) { [Inner **Content**]}"] ` ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
fmt . Sprintf ( "Some text. %s %s. Some more text." , testScPlaceholderRegexp , testScPlaceholderRegexp ) , "" } ,
{ "closed without content" , ` Some text. {{ < inner param1 > }} {{ < / inner > }} . Some more text. ` , ` inner([\"param1\"], false) { []} ` ,
fmt . Sprintf ( "Some text. %s. Some more text." , testScPlaceholderRegexp ) , "" } ,
{ "two shortcodes" , "{{< sc1 >}}{{< sc2 >}}" ,
2016-09-08 15:23:01 -04:00
` map["HAHAHUGOSHORTCODE-1HBHB:sc1([], false) { []}" "HAHAHUGOSHORTCODE-2HBHB:sc2([], false) { []}"] ` ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
testScPlaceholderRegexp + testScPlaceholderRegexp , "" } ,
{ "mix of shortcodes" , ` Hello {{ < sc1 > }} world {{ % sc2 p2 = "2" % }} . And that's it. ` ,
2016-09-08 15:23:01 -04:00
` map["HAHAHUGOSHORTCODE-1HBHB:sc1([], false) { []}" "HAHAHUGOSHORTCODE-2HBHB:sc2([\"p2:2\"] ` ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
fmt . Sprintf ( "Hello %sworld%s. And that's it." , testScPlaceholderRegexp , testScPlaceholderRegexp ) , "" } ,
{ "mix with inner" , ` Hello {{ < sc1 > }} world {{ % inner p2 = "2" % }} Inner {{ % / inner % }} . And that's it. ` ,
2016-09-08 15:23:01 -04:00
` map["HAHAHUGOSHORTCODE-1HBHB:sc1([], false) { []}" "HAHAHUGOSHORTCODE-2HBHB:inner([\"p2:2\"], true) { [Inner]}"] ` ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
fmt . Sprintf ( "Hello %sworld%s. And that's it." , testScPlaceholderRegexp , testScPlaceholderRegexp ) , "" } ,
} {
2017-03-27 14:43:49 -04:00
p , _ := pageFromString ( simplePage , "simple.md" , func ( templ tpl . TemplateHandler ) error {
templ . AddTemplate ( "_internal/shortcodes/tag.html" , ` tag ` )
templ . AddTemplate ( "_internal/shortcodes/sc1.html" , ` sc1 ` )
templ . AddTemplate ( "_internal/shortcodes/sc2.html" , ` sc2 ` )
templ . AddTemplate ( "_internal/shortcodes/inner.html" , ` {{ with .Inner }} {{ . }} {{ end }} ` )
templ . AddTemplate ( "_internal/shortcodes/inner2.html" , ` {{ .Inner }} ` )
templ . AddTemplate ( "_internal/shortcodes/inner3.html" , ` {{ .Inner }} ` )
2017-01-09 19:36:59 -05:00
return nil
} )
2018-04-19 12:06:40 -04:00
counter := 0
2017-05-06 14:15:28 -04:00
s := newShortcodeHandler ( p )
2018-04-19 12:06:40 -04:00
s . placeholderFunc = func ( ) string {
counter ++
return fmt . Sprintf ( "HAHA%s-%dHBHB" , shortcodePlaceholderPrefix , counter )
}
content , err := s . extractShortcodes ( this . input , p . withoutContent ( ) )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
if b , ok := this . expect . ( bool ) ; ok && ! b {
if err == nil {
t . Fatalf ( "[%d] %s: ExtractShortcodes didn't return an expected error" , i , this . name )
} else {
r , _ := regexp . Compile ( this . expectErrorMsg )
if ! r . MatchString ( err . Error ( ) ) {
2015-04-05 15:03:16 -04:00
t . Fatalf ( "[%d] %s: ExtractShortcodes didn't return an expected error message, got %s but expected %s" ,
i , this . name , err . Error ( ) , this . expectErrorMsg )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
}
continue
} else {
if err != nil {
t . Fatalf ( "[%d] %s: failed: %q" , i , this . name , err )
}
}
2017-03-10 14:54:50 -05:00
shortCodes := s . shortcodes
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
var expected string
av := reflect . ValueOf ( this . expect )
switch av . Kind ( ) {
case reflect . String :
expected = av . String ( )
}
r , err := regexp . Compile ( expected )
if err != nil {
t . Fatalf ( "[%d] %s: Failed to compile regexp %q: %q" , i , this . name , expected , err )
}
2018-04-22 08:07:29 -04:00
if strings . Count ( content , shortcodePlaceholderPrefix ) != shortCodes . Len ( ) {
t . Fatalf ( "[%d] %s: Not enough placeholders, found %d" , i , this . name , shortCodes . Len ( ) )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
if ! r . MatchString ( content ) {
2015-04-05 15:03:16 -04:00
t . Fatalf ( "[%d] %s: Shortcode extract didn't match. got %q but expected %q" , i , this . name , content , expected )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
2018-04-22 08:07:29 -04:00
for _ , placeHolder := range shortCodes . Keys ( ) {
sc := shortCodes . getShortcode ( placeHolder )
if ! strings . Contains ( content , placeHolder . ( string ) ) {
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
t . Fatalf ( "[%d] %s: Output does not contain placeholder %q" , i , this . name , placeHolder )
}
if sc . params == nil {
t . Fatalf ( "[%d] %s: Params is nil for shortcode '%s'" , i , this . name , sc . name )
}
}
if this . expectShortCodes != "" {
2015-04-29 13:21:57 -04:00
shortCodesAsStr := fmt . Sprintf ( "map%q" , collectAndSortShortcodes ( shortCodes ) )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
if ! strings . Contains ( shortCodesAsStr , this . expectShortCodes ) {
2018-04-19 12:06:40 -04:00
t . Fatalf ( "[%d] %s: Shortcodes not as expected, got\n%s but expected\n%s" , i , this . name , shortCodesAsStr , this . expectShortCodes )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
}
}
}
2016-01-09 10:11:38 -05:00
func TestShortcodesInSite ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
2016-01-09 10:11:38 -05:00
baseURL := "http://foo/bar"
2016-09-08 15:23:01 -04:00
2016-01-09 10:11:38 -05:00
tests := [ ] struct {
contentPath string
content string
outFile string
expected string
} {
{ "sect/doc1.md" , ` a {{ < b > }} c ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc1/index.html" ) , "<p>abc</p>\n" } ,
2016-01-09 10:11:38 -05:00
// Issue #1642: Multiple shortcodes wrapped in P
// Deliberately forced to pass even if they maybe shouldn't.
{ "sect/doc2.md" , ` a
{ { < b > } }
{ { < c > } }
{ { < d > } }
e ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc2/index.html" ) ,
2016-01-09 10:11:38 -05:00
"<p>a</p>\n\n<p>b<br />\nc\nd</p>\n\n<p>e</p>\n" } ,
{ "sect/doc3.md" , ` a
{ { < b > } }
{ { < c > } }
{ { < d > } }
e ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc3/index.html" ) ,
2016-01-09 10:11:38 -05:00
"<p>a</p>\n\n<p>b<br />\nc</p>\n\nd\n\n<p>e</p>\n" } ,
{ "sect/doc4.md" , ` a
{ { < b > } }
{ { < b > } }
{ { < b > } }
{ { < b > } }
{ { < b > } }
` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc4/index.html" ) ,
2016-01-09 10:11:38 -05:00
"<p>a\nb\nb\nb\nb\nb</p>\n" } ,
2016-06-13 13:10:53 -04:00
// #2192 #2209: Shortcodes in markdown headers
{ "sect/doc5.md" , ` # { { < b > } }
# # { { % c % } } ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc5/index.html" ) , "\n\n<h1 id=\"hahahugoshortcode-1hbhb\">b</h1>\n\n<h2 id=\"hahahugoshortcode-2hbhb\">c</h2>\n" } ,
2016-09-08 15:23:01 -04:00
// #2223 pygments
2017-09-29 04:10:13 -04:00
{ "sect/doc6.md" , "\n```bash\nb = {{< b >}} c = {{% c %}}\n```\n" ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc6/index.html" ) ,
2017-09-29 04:10:13 -04:00
` <span class="nv">b</span> ` } ,
2016-07-03 18:33:08 -04:00
// #2249
{ "sect/doc7.ad" , ` _Shortcodes:_ *b: {{ < b > }} c: {{ % c % }} * ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc7/index.html" ) ,
2016-07-03 18:33:08 -04:00
"<div class=\"paragraph\">\n<p><em>Shortcodes:</em> <strong>b: b c: c</strong></p>\n</div>\n" } ,
2016-07-04 04:49:20 -04:00
{ "sect/doc8.rst" , ` **Shortcodes:** *b: {{ < b > }} c: {{ % c % }} * ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc8/index.html" ) ,
2016-07-04 04:49:20 -04:00
"<div class=\"document\">\n\n\n<p><strong>Shortcodes:</strong> <em>b: b c: c</em></p>\n</div>" } ,
2016-08-01 17:04:44 -04:00
{ "sect/doc9.mmark" , `
-- -
menu :
main :
parent : ' parent '
-- -
* * Shortcodes : * * * b : { { < b > } } c : { { % c % } } * ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc9/index.html" ) ,
2016-07-19 18:40:40 -04:00
"<p><strong>Shortcodes:</strong> <em>b: b c: c</em></p>\n" } ,
2016-08-01 17:04:44 -04:00
// Issue #1229: Menus not available in shortcode.
{ "sect/doc10.md" , ` -- -
menu :
main :
identifier : ' parent '
tags :
- Menu
-- -
* * Menus : * * { { < menu > } } ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc10/index.html" ) ,
2016-08-01 17:04:44 -04:00
"<p><strong>Menus:</strong> 1</p>\n" } ,
// Issue #2323: Taxonomies not available in shortcode.
{ "sect/doc11.md" , ` -- -
tags :
- Bugs
-- -
* * Tags : * * { { < tags > } } ` ,
2017-01-10 04:55:03 -05:00
filepath . FromSlash ( "public/sect/doc11/index.html" ) ,
2016-08-01 17:04:44 -04:00
"<p><strong>Tags:</strong> 2</p>\n" } ,
2016-01-09 10:11:38 -05:00
}
:sparkles: Implement Page bundling and image handling
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes #3651
Closes #3158
Fixes #1014
Closes #2021
Fixes #1240
Updates #3757
2017-07-24 03:00:23 -04:00
sources := make ( [ ] [ 2 ] string , len ( tests ) )
2016-01-09 10:11:38 -05:00
for i , test := range tests {
:sparkles: Implement Page bundling and image handling
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes #3651
Closes #3158
Fixes #1014
Closes #2021
Fixes #1240
Updates #3757
2017-07-24 03:00:23 -04:00
sources [ i ] = [ 2 ] string { filepath . FromSlash ( test . contentPath ) , test . content }
2016-01-09 10:11:38 -05:00
}
2017-03-27 14:43:49 -04:00
addTemplates := func ( templ tpl . TemplateHandler ) error {
2016-07-28 03:30:58 -04:00
templ . AddTemplate ( "_default/single.html" , "{{.Content}}" )
2016-03-09 08:05:31 -05:00
2017-03-27 14:43:49 -04:00
templ . AddTemplate ( "_internal/shortcodes/b.html" , ` b ` )
templ . AddTemplate ( "_internal/shortcodes/c.html" , ` c ` )
templ . AddTemplate ( "_internal/shortcodes/d.html" , ` d ` )
templ . AddTemplate ( "_internal/shortcodes/menu.html" , ` {{ len ( index .Page .Menus "main" ) .Children }} ` )
templ . AddTemplate ( "_internal/shortcodes/tags.html" , ` {{ len .Page .Site .Taxonomies .tags }} ` )
2016-03-09 08:05:31 -05:00
2016-07-28 03:30:58 -04:00
return nil
2016-03-09 08:05:31 -05:00
2016-07-28 03:30:58 -04:00
}
2016-01-09 10:11:38 -05:00
2017-02-04 22:20:06 -05:00
cfg , fs := newTestCfg ( )
cfg . Set ( "defaultContentLanguage" , "en" )
cfg . Set ( "baseURL" , baseURL )
cfg . Set ( "uglyURLs" , false )
cfg . Set ( "verbose" , true )
cfg . Set ( "pygmentsUseClasses" , true )
cfg . Set ( "pygmentsCodefences" , true )
2016-01-09 10:11:38 -05:00
2017-01-10 04:55:03 -05:00
writeSourcesToSource ( t , "content" , fs , sources ... )
2016-07-28 03:30:58 -04:00
2017-02-04 22:20:06 -05:00
s := buildSingleSite ( t , deps . DepsCfg { WithTemplate : addTemplates , Fs : fs , Cfg : cfg } , BuildCfg { } )
2017-02-17 14:52:50 -05:00
th := testHelper { s . Cfg , s . Fs , t }
2016-01-09 10:11:38 -05:00
for _ , test := range tests {
2017-11-30 06:15:52 -05:00
if strings . HasSuffix ( test . contentPath , ".ad" ) && ! helpers . HasAsciidoc ( ) {
2016-07-03 18:33:08 -04:00
fmt . Println ( "Skip Asciidoc test case as no Asciidoc present." )
continue
2016-07-04 04:49:20 -04:00
} else if strings . HasSuffix ( test . contentPath , ".rst" ) && ! helpers . HasRst ( ) {
fmt . Println ( "Skip Rst test case as no rst2html present." )
continue
2017-09-25 02:59:02 -04:00
} else if strings . Contains ( test . expected , "code" ) {
2016-09-08 15:23:01 -04:00
fmt . Println ( "Skip Pygments test case as no pygments present." )
continue
2016-07-03 18:33:08 -04:00
}
2016-07-04 04:49:20 -04:00
2017-02-17 15:14:52 -05:00
th . assertFileContent ( test . outFile , test . expected )
2016-01-09 10:11:38 -05:00
}
}
2017-05-06 14:15:28 -04:00
func TestShortcodeMultipleOutputFormats ( t * testing . T ) {
t . Parallel ( )
siteConfig := `
baseURL = "http://example.com/blog"
paginate = 1
disableKinds = [ "section" , "taxonomy" , "taxonomyTerm" , "RSS" , "sitemap" , "robotsTXT" , "404" ]
[ outputs ]
home = [ "HTML" , "AMP" , "Calendar" ]
page = [ "HTML" , "AMP" , "JSON" ]
`
pageTemplate := ` -- -
title : "%s"
-- -
# Doc
{ { < myShort > } }
{ { < noExt > } }
{ { % % onlyHTML % % } }
{ { < myInner > } } { { < myShort > } } { { < / myInner > } }
`
pageTemplateCSVOnly := ` -- -
title : "%s"
outputs : [ "CSV" ]
-- -
# Doc
CSV : { { < myShort > } }
`
pageTemplateShortcodeNotFound := ` -- -
title : "%s"
outputs : [ "CSV" ]
-- -
# Doc
NotFound : { { < thisDoesNotExist > } }
`
mf := afero . NewMemMapFs ( )
th , h := newTestSitesFromConfig ( t , mf , siteConfig ,
"layouts/_default/single.html" , ` Single HTML: {{ .Title }} | {{ .Content }} ` ,
"layouts/_default/single.json" , ` Single JSON: {{ .Title }} | {{ .Content }} ` ,
"layouts/_default/single.csv" , ` Single CSV: {{ .Title }} | {{ .Content }} ` ,
"layouts/index.html" , ` Home HTML: {{ .Title }} | {{ .Content }} ` ,
"layouts/index.amp.html" , ` Home AMP: {{ .Title }} | {{ .Content }} ` ,
"layouts/index.ics" , ` Home Calendar: {{ .Title }} | {{ .Content }} ` ,
"layouts/shortcodes/myShort.html" , ` ShortHTML ` ,
"layouts/shortcodes/myShort.amp.html" , ` ShortAMP ` ,
"layouts/shortcodes/myShort.csv" , ` ShortCSV ` ,
"layouts/shortcodes/myShort.ics" , ` ShortCalendar ` ,
"layouts/shortcodes/myShort.json" , ` ShortJSON ` ,
"layouts/shortcodes/noExt" , ` ShortNoExt ` ,
"layouts/shortcodes/onlyHTML.html" , ` ShortOnlyHTML ` ,
"layouts/shortcodes/myInner.html" , ` myInner:-- {{- .Inner -}} -- ` ,
)
fs := th . Fs
writeSource ( t , fs , "content/_index.md" , fmt . Sprintf ( pageTemplate , "Home" ) )
writeSource ( t , fs , "content/sect/mypage.md" , fmt . Sprintf ( pageTemplate , "Single" ) )
writeSource ( t , fs , "content/sect/mycsvpage.md" , fmt . Sprintf ( pageTemplateCSVOnly , "Single CSV" ) )
writeSource ( t , fs , "content/sect/notfound.md" , fmt . Sprintf ( pageTemplateShortcodeNotFound , "Single CSV" ) )
2018-03-15 04:37:30 -04:00
err := h . Build ( BuildCfg { } )
require . Equal ( t , "logged 1 error(s)" , err . Error ( ) )
2017-05-06 14:15:28 -04:00
require . Len ( t , h . Sites , 1 )
s := h . Sites [ 0 ]
home := s . getPage ( KindHome )
require . NotNil ( t , home )
require . Len ( t , home . outputFormats , 3 )
th . assertFileContent ( "public/index.html" ,
"Home HTML" ,
"ShortHTML" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortHTML--" ,
)
th . assertFileContent ( "public/amp/index.html" ,
"Home AMP" ,
"ShortAMP" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortAMP--" ,
)
th . assertFileContent ( "public/index.ics" ,
"Home Calendar" ,
"ShortCalendar" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortCalendar--" ,
)
th . assertFileContent ( "public/sect/mypage/index.html" ,
"Single HTML" ,
"ShortHTML" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortHTML--" ,
)
th . assertFileContent ( "public/sect/mypage/index.json" ,
"Single JSON" ,
"ShortJSON" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortJSON--" ,
)
th . assertFileContent ( "public/amp/sect/mypage/index.html" ,
// No special AMP template
"Single HTML" ,
"ShortAMP" ,
"ShortNoExt" ,
"ShortOnlyHTML" ,
"myInner:--ShortAMP--" ,
)
th . assertFileContent ( "public/sect/mycsvpage/index.csv" ,
"Single CSV" ,
"ShortCSV" ,
)
th . assertFileContent ( "public/sect/notfound/index.csv" ,
"NotFound:" ,
"thisDoesNotExist" ,
)
require . Equal ( t , uint64 ( 1 ) , s . Log . LogCountForLevel ( jww . LevelError ) )
}
2018-04-22 08:07:29 -04:00
func collectAndSortShortcodes ( shortcodes * orderedMap ) [ ] string {
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
var asArray [ ] string
2018-04-22 08:07:29 -04:00
for _ , key := range shortcodes . Keys ( ) {
sc := shortcodes . getShortcode ( key )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
asArray = append ( asArray , fmt . Sprintf ( "%s:%s" , key , sc ) )
}
sort . Strings ( asArray )
return asArray
}
2015-05-19 16:00:48 -04:00
func BenchmarkReplaceShortcodeTokens ( b * testing . B ) {
2015-11-13 15:21:03 -05:00
type input struct {
in [ ] byte
replacements map [ string ] string
expect [ ] byte
}
2015-05-19 16:00:48 -04:00
data := [ ] struct {
input string
replacements map [ string ] string
2015-11-13 15:21:03 -05:00
expect [ ] byte
2015-05-19 16:00:48 -04:00
} {
2016-09-08 15:23:01 -04:00
{ "Hello HAHAHUGOSHORTCODE-1HBHB." , map [ string ] string { "HAHAHUGOSHORTCODE-1HBHB" : "World" } , [ ] byte ( "Hello World." ) } ,
{ strings . Repeat ( "A" , 100 ) + " HAHAHUGOSHORTCODE-1HBHB." , map [ string ] string { "HAHAHUGOSHORTCODE-1HBHB" : "Hello World" } , [ ] byte ( strings . Repeat ( "A" , 100 ) + " Hello World." ) } ,
{ strings . Repeat ( "A" , 500 ) + " HAHAHUGOSHORTCODE-1HBHB." , map [ string ] string { "HAHAHUGOSHORTCODE-1HBHB" : "Hello World" } , [ ] byte ( strings . Repeat ( "A" , 500 ) + " Hello World." ) } ,
{ strings . Repeat ( "ABCD " , 500 ) + " HAHAHUGOSHORTCODE-1HBHB." , map [ string ] string { "HAHAHUGOSHORTCODE-1HBHB" : "Hello World" } , [ ] byte ( strings . Repeat ( "ABCD " , 500 ) + " Hello World." ) } ,
{ strings . Repeat ( "A " , 3000 ) + " HAHAHUGOSHORTCODE-1HBHB." + strings . Repeat ( "BC " , 1000 ) + " HAHAHUGOSHORTCODE-1HBHB." , map [ string ] string { "HAHAHUGOSHORTCODE-1HBHB" : "Hello World" } , [ ] byte ( strings . Repeat ( "A " , 3000 ) + " Hello World." + strings . Repeat ( "BC " , 1000 ) + " Hello World." ) } ,
2015-11-13 15:21:03 -05:00
}
2016-03-23 05:10:28 -04:00
var in = make ( [ ] input , b . N * len ( data ) )
2015-11-13 15:21:03 -05:00
var cnt = 0
for i := 0 ; i < b . N ; i ++ {
for _ , this := range data {
in [ cnt ] = input { [ ] byte ( this . input ) , this . replacements , this . expect }
cnt ++
}
2015-05-19 16:00:48 -04:00
}
2015-11-13 15:21:03 -05:00
2015-05-19 16:00:48 -04:00
b . ResetTimer ( )
2015-11-13 15:21:03 -05:00
cnt = 0
2015-05-19 16:00:48 -04:00
for i := 0 ; i < b . N ; i ++ {
2015-11-13 15:21:03 -05:00
for j := range data {
currIn := in [ cnt ]
cnt ++
results , err := replaceShortcodeTokens ( currIn . in , "HUGOSHORTCODE" , currIn . replacements )
2015-05-19 16:00:48 -04:00
2015-11-13 15:21:03 -05:00
if err != nil {
b . Fatalf ( "[%d] failed: %s" , i , err )
continue
}
if len ( results ) != len ( currIn . expect ) {
b . Fatalf ( "[%d] replaceShortcodeTokens, got \n%q but expected \n%q" , j , results , currIn . expect )
2015-05-19 16:00:48 -04:00
}
}
}
}
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
func TestReplaceShortcodeTokens ( t * testing . T ) {
2017-02-04 22:20:06 -05:00
t . Parallel ( )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
for i , this := range [ ] struct {
2015-01-28 22:39:59 -05:00
input string
2015-01-28 22:11:41 -05:00
prefix string
replacements map [ string ] string
expect interface { }
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
} {
2016-09-08 15:23:01 -04:00
{ "Hello HAHAPREFIX-1HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "Hello World." } ,
{ "Hello HAHAPREFIX-1@}@." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , false } ,
{ "HAHAPREFIX2-1HBHB" , "PREFIX2" , map [ string ] string { "HAHAPREFIX2-1HBHB" : "World" } , "World" } ,
2015-10-20 14:35:12 -04:00
{ "Hello World!" , "PREFIX2" , map [ string ] string { } , "Hello World!" } ,
2016-09-08 15:23:01 -04:00
{ "!HAHAPREFIX-1HBHB" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "!World" } ,
{ "HAHAPREFIX-1HBHB!" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "World!" } ,
{ "!HAHAPREFIX-1HBHB!" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "!World!" } ,
{ "_{_PREFIX-1HBHB" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "_{_PREFIX-1HBHB" } ,
{ "Hello HAHAPREFIX-1HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "To You My Old Friend Who Told Me This Fantastic Story" } , "Hello To You My Old Friend Who Told Me This Fantastic Story." } ,
{ "A HAHAA-1HBHB asdf HAHAA-2HBHB." , "A" , map [ string ] string { "HAHAA-1HBHB" : "v1" , "HAHAA-2HBHB" : "v2" } , "A v1 asdf v2." } ,
{ "Hello HAHAPREFIX2-1HBHB. Go HAHAPREFIX2-2HBHB, Go, Go HAHAPREFIX2-3HBHB Go Go!." , "PREFIX2" , map [ string ] string { "HAHAPREFIX2-1HBHB" : "Europe" , "HAHAPREFIX2-2HBHB" : "Jonny" , "HAHAPREFIX2-3HBHB" : "Johnny" } , "Hello Europe. Go Jonny, Go, Go Johnny Go Go!." } ,
{ "A HAHAPREFIX-2HBHB HAHAPREFIX-1HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" } , "A B A." } ,
{ "A HAHAPREFIX-1HBHB HAHAPREFIX-2" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" } , false } ,
{ "A HAHAPREFIX-1HBHB but not the second." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" } , "A A but not the second." } ,
{ "An HAHAPREFIX-1HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" } , "An A." } ,
{ "An HAHAPREFIX-1HBHB HAHAPREFIX-2HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" } , "An A B." } ,
{ "A HAHAPREFIX-1HBHB HAHAPREFIX-2HBHB HAHAPREFIX-3HBHB HAHAPREFIX-1HBHB HAHAPREFIX-3HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" , "HAHAPREFIX-3HBHB" : "C" } , "A A B C A C." } ,
{ "A HAHAPREFIX-1HBHB HAHAPREFIX-2HBHB HAHAPREFIX-3HBHB HAHAPREFIX-1HBHB HAHAPREFIX-3HBHB." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "A" , "HAHAPREFIX-2HBHB" : "B" , "HAHAPREFIX-3HBHB" : "C" } , "A A B C A C." } ,
2015-06-21 07:08:30 -04:00
// Issue #1148 remove p-tags 10 =>
2016-09-08 15:23:01 -04:00
{ "Hello <p>HAHAPREFIX-1HBHB</p>. END." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "Hello World. END." } ,
{ "Hello <p>HAHAPREFIX-1HBHB</p>. <p>HAHAPREFIX-2HBHB</p> END." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" , "HAHAPREFIX-2HBHB" : "THE" } , "Hello World. THE END." } ,
{ "Hello <p>HAHAPREFIX-1HBHB. END</p>." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "Hello <p>World. END</p>." } ,
{ "<p>Hello HAHAPREFIX-1HBHB</p>. END." , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "<p>Hello World</p>. END." } ,
{ "Hello <p>HAHAPREFIX-1HBHB12" , "PREFIX" , map [ string ] string { "HAHAPREFIX-1HBHB" : "World" } , "Hello <p>World12" } ,
{ "Hello HAHAP-1HBHB. HAHAP-1HBHB-HAHAP-1HBHB HAHAP-1HBHB HAHAP-1HBHB HAHAP-1HBHB END" , "P" , map [ string ] string { "HAHAP-1HBHB" : strings . Repeat ( "BC" , 100 ) } ,
2015-06-21 07:08:30 -04:00
fmt . Sprintf ( "Hello %s. %s-%s %s %s %s END" ,
strings . Repeat ( "BC" , 100 ) , strings . Repeat ( "BC" , 100 ) , strings . Repeat ( "BC" , 100 ) , strings . Repeat ( "BC" , 100 ) , strings . Repeat ( "BC" , 100 ) , strings . Repeat ( "BC" , 100 ) ) } ,
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
} {
2015-10-20 14:35:12 -04:00
2015-06-21 07:08:30 -04:00
results , err := replaceShortcodeTokens ( [ ] byte ( this . input ) , this . prefix , this . replacements )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
if b , ok := this . expect . ( bool ) ; ok && ! b {
if err == nil {
t . Errorf ( "[%d] replaceShortcodeTokens didn't return an expected error" , i )
}
} else {
if err != nil {
t . Errorf ( "[%d] failed: %s" , i , err )
continue
}
2015-01-28 22:39:59 -05:00
if ! reflect . DeepEqual ( results , [ ] byte ( this . expect . ( string ) ) ) {
2015-06-21 07:08:30 -04:00
t . Errorf ( "[%d] replaceShortcodeTokens, got \n%q but expected \n%q" , i , results , this . expect )
Shortcode rewrite, take 2
This commit contains a restructuring and partial rewrite of the shortcode handling.
Prior to this commit rendering of the page content was mingled with handling of the shortcodes. This led to several oddities.
The new flow is:
1. Shortcodes are extracted from page and replaced with placeholders.
2. Shortcodes are processed and rendered
3. Page is processed
4. The placeholders are replaced with the rendered shortcodes
The handling of summaries is also made simpler by this.
This commit also introduces some other chenges:
1. distinction between shortcodes that need further processing and those who do not:
* `{{< >}}`: Typically raw HTML. Will not be processed.
* `{{% %}}`: Will be processed by the page's markup engine (Markdown or (infuture) Asciidoctor)
The above also involves a new shortcode-parser, with lexical scanning inspired by Rob Pike's talk called "Lexical Scanning in Go",
which should be easier to understand, give better error messages and perform better.
2. If you want to exclude a shortcode from being processed (for documentation etc.), the inner part of the shorcode must be commented out, i.e. `{{%/* movie 47238zzb */%}}`. See the updated shortcode section in the documentation for further examples.
The new parser supports nested shortcodes. This isn't new, but has two related design choices worth mentioning:
* The shortcodes will be rendered individually, so If both `{{< >}}` and `{{% %}}` are used in the nested hierarchy, one will be passed through the page's markdown processor, the other not.
* To avoid potential costly overhead of always looking far ahead for a possible closing tag, this implementation looks at the template itself, and is branded as a container with inner content if it contains a reference to `.Inner`
Fixes #565
Fixes #480
Fixes #461
And probably some others.
2014-10-27 16:48:30 -04:00
}
}
}
2014-02-25 23:57:31 -05:00
}
2017-05-06 14:15:28 -04:00
func TestScKey ( t * testing . T ) {
require . Equal ( t , scKey { Suffix : "xml" , ShortcodePlaceholder : "ABCD" } ,
newScKey ( media . XMLType , "ABCD" ) )
2017-07-02 04:46:28 -04:00
require . Equal ( t , scKey { Lang : "en" , Suffix : "html" , OutputFormat : "AMP" , ShortcodePlaceholder : "EFGH" } ,
newScKeyFromLangAndOutputFormat ( "en" , output . AMPFormat , "EFGH" ) )
2017-05-06 14:15:28 -04:00
require . Equal ( t , scKey { Suffix : "html" , ShortcodePlaceholder : "IJKL" } ,
newDefaultScKey ( "IJKL" ) )
}
2018-04-22 08:07:29 -04:00
func TestPreserveShortcodeOrder ( t * testing . T ) {
t . Parallel ( )
assert := require . New ( t )
contentTemplate := ` -- -
title : doc % d
weight : % d
-- -
# doc
2018-04-23 02:09:56 -04:00
{ { < s1 > } } { { < s2 > } } { { < s3 > } } { { < s4 > } } { { < s5 > } }
{ { < nested > } }
{ { < ordinal > } }
{ { < ordinal > } }
{ { < ordinal > } }
{ { < / nested > } }
2018-04-22 08:07:29 -04:00
`
2018-04-23 02:09:56 -04:00
ordinalShortcodeTemplate := ` ordinal: {{ .Ordinal }} `
nestedShortcode := ` outer ordinal: {{ .Ordinal }} inner: {{ .Inner }} `
shortCodeTemplate := ` v%d: {{ .Ordinal }} | `
2018-04-22 08:07:29 -04:00
var shortcodes [ ] string
var content [ ] string
2018-04-23 02:09:56 -04:00
shortcodes = append ( shortcodes , [ ] string { "shortcodes/nested.html" , nestedShortcode } ... )
shortcodes = append ( shortcodes , [ ] string { "shortcodes/ordinal.html" , ordinalShortcodeTemplate } ... )
2018-04-22 08:07:29 -04:00
for i := 1 ; i <= 5 ; i ++ {
shortcodes = append ( shortcodes , [ ] string { fmt . Sprintf ( "shortcodes/s%d.html" , i ) , fmt . Sprintf ( shortCodeTemplate , i ) } ... )
}
for i := 1 ; i <= 3 ; i ++ {
content = append ( content , [ ] string { fmt . Sprintf ( "p%d.md" , i ) , fmt . Sprintf ( contentTemplate , i , i ) } ... )
}
builder := newTestSitesBuilder ( t ) . WithDefaultMultiSiteConfig ( )
builder . WithContent ( content ... ) . WithTemplatesAdded ( shortcodes ... ) . CreateSites ( ) . Build ( BuildCfg { } )
s := builder . H . Sites [ 0 ]
assert . Equal ( 3 , len ( s . RegularPages ) )
p1 := s . RegularPages [ 0 ]
2018-04-23 02:09:56 -04:00
if ! strings . Contains ( string ( p1 . content ( ) ) , ` v1: 0|v2: 1|v3: 2|v4: 3|v5: 4| ` ) {
t . Fatal ( p1 . content ( ) )
}
// Check nested behaviour
if ! strings . Contains ( string ( p1 . content ( ) ) , ` outer ordinal : 5 inner :
ordinal : 0
ordinal : 1
ordinal : 2 ` ) {
2018-04-22 08:07:29 -04:00
t . Fatal ( p1 . content ( ) )
}
}