mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-14 12:02:53 +00:00
hugolib: Add zero-based Ordinal to shortcode
The count starts at 0 relative to the shortcode's parent: Either the page or the surrounding shortcode. Access it in a shortcode like this: ```bash Ordinal is {{ .Ordinal }} ``` Note that this is a shared ordinal for all shortcodes in the relevant context, so, as an example, you have this in a content page: ```markdown This is a shortcode: {{< hello >}} This is another shortcode: {{< hugo >}} The `.Ordinal` you get in the two shortcodes above is 0 and 1. ``` See #3359
This commit is contained in:
parent
24c662ce6b
commit
3decf4a327
2 changed files with 38 additions and 10 deletions
|
@ -40,7 +40,11 @@ type ShortcodeWithPage struct {
|
||||||
Page *PageWithoutContent
|
Page *PageWithoutContent
|
||||||
Parent *ShortcodeWithPage
|
Parent *ShortcodeWithPage
|
||||||
IsNamedParams bool
|
IsNamedParams bool
|
||||||
scratch *Scratch
|
|
||||||
|
// Zero-based oridinal in relation to its parent.
|
||||||
|
Ordinal int
|
||||||
|
|
||||||
|
scratch *Scratch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Site returns information about the current site.
|
// Site returns information about the current site.
|
||||||
|
@ -122,6 +126,7 @@ type shortcode struct {
|
||||||
name string
|
name string
|
||||||
inner []interface{} // string or nested shortcode
|
inner []interface{} // string or nested shortcode
|
||||||
params interface{} // map or array
|
params interface{} // map or array
|
||||||
|
ordinal int
|
||||||
err error
|
err error
|
||||||
doMarkup bool
|
doMarkup bool
|
||||||
}
|
}
|
||||||
|
@ -287,7 +292,7 @@ func renderShortcode(
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &ShortcodeWithPage{Params: sc.params, Page: p, Parent: parent}
|
data := &ShortcodeWithPage{Ordinal: sc.ordinal, Params: sc.params, Page: p, Parent: parent}
|
||||||
if sc.params != nil {
|
if sc.params != nil {
|
||||||
data.IsNamedParams = reflect.TypeOf(sc.params).Kind() == reflect.Map
|
data.IsNamedParams = reflect.TypeOf(sc.params).Kind() == reflect.Map
|
||||||
}
|
}
|
||||||
|
@ -449,12 +454,13 @@ var errShortCodeIllegalState = errors.New("Illegal shortcode state")
|
||||||
// pageTokens state:
|
// pageTokens state:
|
||||||
// - before: positioned just before the shortcode start
|
// - before: positioned just before the shortcode start
|
||||||
// - after: shortcode(s) consumed (plural when they are nested)
|
// - after: shortcode(s) consumed (plural when they are nested)
|
||||||
func (s *shortcodeHandler) extractShortcode(pt *pageTokens, p *PageWithoutContent) (*shortcode, error) {
|
func (s *shortcodeHandler) extractShortcode(ordinal int, pt *pageTokens, p *PageWithoutContent) (*shortcode, error) {
|
||||||
sc := &shortcode{}
|
sc := &shortcode{ordinal: ordinal}
|
||||||
var isInner = false
|
var isInner = false
|
||||||
|
|
||||||
var currItem item
|
var currItem item
|
||||||
var cnt = 0
|
var cnt = 0
|
||||||
|
var nestedOrdinal = 0
|
||||||
|
|
||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
|
@ -470,7 +476,8 @@ Loop:
|
||||||
if cnt > 0 {
|
if cnt > 0 {
|
||||||
// nested shortcode; append it to inner content
|
// nested shortcode; append it to inner content
|
||||||
pt.backup3(currItem, next)
|
pt.backup3(currItem, next)
|
||||||
nested, err := s.extractShortcode(pt, p)
|
nested, err := s.extractShortcode(nestedOrdinal, pt, p)
|
||||||
|
nestedOrdinal++
|
||||||
if nested.name != "" {
|
if nested.name != "" {
|
||||||
s.nameSet[nested.name] = true
|
s.nameSet[nested.name] = true
|
||||||
}
|
}
|
||||||
|
@ -593,6 +600,7 @@ func (s *shortcodeHandler) extractShortcodes(stringToParse string, p *PageWithou
|
||||||
// … it's safe to keep some "global" state
|
// … it's safe to keep some "global" state
|
||||||
var currItem item
|
var currItem item
|
||||||
var currShortcode shortcode
|
var currShortcode shortcode
|
||||||
|
var ordinal int
|
||||||
|
|
||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
|
@ -605,7 +613,7 @@ Loop:
|
||||||
// let extractShortcode handle left delim (will do so recursively)
|
// let extractShortcode handle left delim (will do so recursively)
|
||||||
pt.backup()
|
pt.backup()
|
||||||
|
|
||||||
currShortcode, err := s.extractShortcode(pt, p)
|
currShortcode, err := s.extractShortcode(ordinal, pt, p)
|
||||||
|
|
||||||
if currShortcode.name != "" {
|
if currShortcode.name != "" {
|
||||||
s.nameSet[currShortcode.name] = true
|
s.nameSet[currShortcode.name] = true
|
||||||
|
@ -621,6 +629,7 @@ Loop:
|
||||||
|
|
||||||
placeHolder := s.createShortcodePlaceholder()
|
placeHolder := s.createShortcodePlaceholder()
|
||||||
result.WriteString(placeHolder)
|
result.WriteString(placeHolder)
|
||||||
|
ordinal++
|
||||||
s.shortcodes.Add(placeHolder, currShortcode)
|
s.shortcodes.Add(placeHolder, currShortcode)
|
||||||
case tEOF:
|
case tEOF:
|
||||||
break Loop
|
break Loop
|
||||||
|
|
|
@ -894,17 +894,28 @@ weight: %d
|
||||||
---
|
---
|
||||||
# doc
|
# doc
|
||||||
|
|
||||||
{{< increment >}}{{< s1 >}}{{< increment >}}{{< s2 >}}{{< increment >}}{{< s3 >}}{{< increment >}}{{< s4 >}}{{< increment >}}{{< s5 >}}
|
{{< s1 >}}{{< s2 >}}{{< s3 >}}{{< s4 >}}{{< s5 >}}
|
||||||
|
|
||||||
|
{{< nested >}}
|
||||||
|
{{< ordinal >}}
|
||||||
|
{{< ordinal >}}
|
||||||
|
{{< ordinal >}}
|
||||||
|
{{< /nested >}}
|
||||||
|
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
shortCodeTemplate := `v%d: {{ .Page.Scratch.Get "v" }}|`
|
ordinalShortcodeTemplate := `ordinal: {{ .Ordinal }}`
|
||||||
|
|
||||||
|
nestedShortcode := `outer ordinal: {{ .Ordinal }} inner: {{ .Inner }}`
|
||||||
|
|
||||||
|
shortCodeTemplate := `v%d: {{ .Ordinal }}|`
|
||||||
|
|
||||||
var shortcodes []string
|
var shortcodes []string
|
||||||
var content []string
|
var content []string
|
||||||
|
|
||||||
shortcodes = append(shortcodes, []string{"shortcodes/increment.html", `{{ .Page.Scratch.Add "v" 1}}`}...)
|
shortcodes = append(shortcodes, []string{"shortcodes/nested.html", nestedShortcode}...)
|
||||||
|
shortcodes = append(shortcodes, []string{"shortcodes/ordinal.html", ordinalShortcodeTemplate}...)
|
||||||
|
|
||||||
for i := 1; i <= 5; i++ {
|
for i := 1; i <= 5; i++ {
|
||||||
shortcodes = append(shortcodes, []string{fmt.Sprintf("shortcodes/s%d.html", i), fmt.Sprintf(shortCodeTemplate, i)}...)
|
shortcodes = append(shortcodes, []string{fmt.Sprintf("shortcodes/s%d.html", i), fmt.Sprintf(shortCodeTemplate, i)}...)
|
||||||
|
@ -923,7 +934,15 @@ weight: %d
|
||||||
|
|
||||||
p1 := s.RegularPages[0]
|
p1 := s.RegularPages[0]
|
||||||
|
|
||||||
if !strings.Contains(string(p1.content()), `v1: 1|v2: 2|v3: 3|v4: 4|v5: 5`) {
|
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`) {
|
||||||
t.Fatal(p1.content())
|
t.Fatal(p1.content())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue