I have this following layout, with jekyll 3.7.3;
declare A = apple
include file.html > declare A = orange
print A => orange
I am confused to how did A=orange leaked to the parent layout, in the jekyll's doc, says that the variables assess thru layout in the liquid tag. Does this apply to the include as well? It makes no sense in where child layout overwritten the parent layout, as it is saying in the github conversation and this conversation.
So my question is how is this inheritance work?
From what I understand about inheritance, there should be some control how the child variable be overwrite the parent variable. From the document, I believe it is through the variable layout. Then this should look like this;
declare A = apple
include file.html > declare layout.A = orange
print A => apple
Other case is;
declare A = apple
include file.html > print A => apple
declare A = orange
print A => orange
What is the point of having an argument in the include if the child include inheritances the value without explicitly tells it to.
also with the leak variables into the include child, would mean the child include is not isolated any more for the purpose of special case like it is saying here
Includes and layouts are not the same.
While generating a site, Jekyll does a lot of things in a particular order.
Read pages's datas
Render liquid
make necessary includes
compute liquid tags and filters
Render html in case the document is markdown
Render layout
When it renders liquid :
=== page.html
include other.html
print a
assign: a = apple
print a
include other.html
=== end page.html
Becomes a pile of code which is processed like this :
=== page.html
====== other.html
print a ------> nil
assign: a = orange
print a ------> orange
====== end other.html
print a ------> orange
assign: a = apple
print a ------> apple
====== other.html
print a ------> apple
assign: a = orange
print a ------> orange
====== end other.html
=== end page.html
Liquid tags are executed exactly in the order they appear in code, and variables (the local variables assigned in page body, not the one in front matter that are freezed and cannot be changed) are global and can be overridden from page or any child include.
After this, it renders HTML if necessary, and "spits" page's {{ content }} in the layout that knows nothing about page's local variables and can only see page's variables defined in front matter.
Related
We can define template name via {{define "home"}}, and then load it in other (parent) template via {{template "home"}}.
How I can load template via variable value {{template .TemplateName}}. Or it's impossible?
Unfortunately you can't.
The syntax of the {{template}} action:
{{template "name"}}
The template with the specified name is executed with nil data.
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
The name of the template to be included is a constant string, it is not a pipeline which could vary during execution based on parameters.
If the allowed syntax would be:
{{template pipeline}}
then you could use something like {{template .TemplName}} but since the syntax only allows a constant string, you can't.
Reasoning from Rob why dynamic template invocation is not allowed (source):
We want the template language to be statically analyzable so the context of a template's invocation is clear, checkable, and lockdownable. If an invocation point is totally dynamic, this can't be done. Similarly, if a template can belong to multiple sets, its context can differ between sets in a way that would require all sets to be analyzed simultaneously. Since both these constraints are easy to work around if you want to, at the cost of losing those static checks in a higher-level package, it seemed wise to control the situation in the base template implementation. A higher-level package, such as a hypothetical HTML-only wrapper, can guarantee no workarounds more easily if the constraints are clear.
Alternative #1: Execute Includable Template First
What you can do is execute the template you would want to include first, and insert the result where you want to include it. You can use special types not to escape the result of the inner template when inserting, for example html.HTML in case of HTML templates.
See this example:
func main() {
t := template.Must(template.New("t").Parse(t))
template.Must(t.New("t1").Parse(t1))
params := struct {
Name string
Value interface{}
}{"t1", nil}
b := bytes.Buffer{}
t.ExecuteTemplate(&b, params.Name, nil)
params.Value = template.HTML(b.String())
t.Execute(os.Stdout, params)
}
const t = `<html><body>
Now I will include template with name: {{.Name}}
{{.Value}}
</body>/html>`
const t1 = `I'm template <b>t1</b>.`
Output:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
Try it on the Go Playground.
The result of template t1 was inserted unescaped. If you leave out template.HTML:
params.Value = b.String()
t1 would be inserted escaped, like this:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
Alternative #2: Restructure Templates
You can restructure your templates not to be in situations where you would want to include a template with varying names.
Example: you might want to create pages where you have a page template something like this:
<html><body>
Title, headers etc.
{{template .Page}}
Footers
</body></html>
You can restructure it to be something like this:
header template:
<html><body>
Title, headers, etc.
footer template:
Footers
</body></html
And your page templates would include header and footer like this:
{{template "header" .}}
Page content comes here.
{{template "footer" .}}
Alternative #3: Use {{if}} action and predefined names
If you know the template names prior and it is not an exhausting list, you can use the {{if}} template action to include the desired template. Example:
{{if eq .Name "page1"}}
{{template "page1" .}}
{{else if eq .Name "page2"}}
{{template "page2" .}}
...
{{end}}
Alternative #4: Modifying the static template text
The idea here is that you could modify the static text of the outer template manually and insert the name of the inner template you want to include.
The downside of this method is that after inserting the name of the inner template, you have to re-parse the template, so I don't recommend this.
I have 3 images that start with the PAGENAME and have different endings. Now I want to display them in a gallery like this:
<gallery>
File:{{PAGENAME}}.png|Adult
File:{{PAGENAME}} Egg.png|Egg
File:{{PAGENAME}} Baby.png|Baby
</gallery>
But the PAGENAME doesn't transclude and the gallery stays empty.
How can I achieve that?
Thanks
edit: I would also like to add the mode="slideshow" parameter to it
Html tags have priority in page content parsing, which means that any parser function inside is interpreted as string. So you need to turn them into a parser function, using #tag
{{#tag:gallery | content }}
Note that you cannot have literal pipes inside content, you have to turn them into a template call, using build-in pipe template:
{{!}}
You'll end up with this code:
{{#tag:gallery |
File:{{PAGENAME}}.png{{!}}Adult
File:{{PAGENAME}} Egg.png{{!}}Egg
File:{{PAGENAME}} Baby.png{{!}}Baby
|mode=slideshow}}
My Python Sphinx restructuredtext project includes empty 1st level sections. How can I redirect users to the first subsection of the HTML output without resorting to raw Javascript?
Hi,
index.rst is as follows:
Title
=====
.. toctree::
:hidden:
foo.rst
bar.rst
To avoid displaying a blank index.html page, I automatically display the 1st subsection, namely foo.html, via the following trick:
Title
=====
.. raw:: html
<script type="text/javascript">
window.location.href = "foo.html"
</script>
.. toctree::
:hidden:
foo.rst
bar.rst
Is it possible to apply the same behavior to all sections with Jinja in Python-Sphinx, i.e: if section body is empty and subsections exists, then fall back to 1st subsection?
Add a label.
If you place a label directly before a section title, you can reference to it with :ref:[backtick]label-name[backtick]. For example:
.. _my-reference-label:
Section to cross-reference
--------------------------
This is the text of the section.
It refers to the section itself, see :ref:`my-reference-label`.
The :ref: role would then generate a link to the section, with the link title being “Section to cross-reference”. This works just as well when section and reference are in different source files.
I'm using Jekll and kramdown to build a static side.
I am often repeating the same large paths to things in assets in image tags, like:
![Some image title](/assets/foo/bar/2019-03-17/more/stuff/groundbreaking-plot.svg)
Can I somehow save the /assets/foo/bar/2019-03-17/more/stuff portion in a per-page variable so I can refer to it succintly in the markdown, like:
![Some image title](??assets_for_this_entry??/groundbreaking-plot.svg)
Yes, you can set it in the front matter. You can set custom variables for each page.
---
... other stuff in front matter
myPath: /assets/foo/bar/2019-03-17/more/stuff
---
![]({{ page.myPath }}/image.svg }}}
I have a jekyll site where I post a lot of shell examples in code blocks. I struggle to visually delineate between the script/shell commands and their output of the commmands.
Generated html:
<pre><code class="language-powershell">
function DemoCode {
return 'rab', 'oof'
}
DemoCode
rab
oof
</code></pre>
In this example, the last two lines need to be obviously the output from the first 4 lines.
Markdown is currently just normal triple-backtick with a powershell tag:
```powershell
function DemoCode {
return 'rab', 'oof'
}
DemoCode
rab
oof
```
I'd prefer to avoid splitting it into a second code block. Wordpress let me do this with inline style tags, but it was a pig of a job.
This isn't a good solution for me but I could have a separate code block with the 'plaintext' tag to the syntax highlighter:
The best I have so far is indeed with separate code blocks. If I apply the 'plaintext' tag to rouge, then at least I don't get syntax highlighting, which helps. But the generated html still inherits the same CSS from .highlight.
Markdown:
```powershell
function Write-Stuff {
Write-Output $Stuff
}
```
```plaintext
Output I would like with different color and background-color
```
I still need that to inherit different CSS, though. Generated HTML:
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#this is formatted with md code block and powershell tag</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#formatted with md code block and plaintext tag
</code></pre></div></div>
If you want to go with separate code blocks, you can use a block IAL to set a custom class on the syntax highlighted blocks:
{:.my-custom-class}
``` powershell
function Write-Stuff {
Write-Output $Stuff
}
```
This would insert the my-custom-class right next to language-powershell highlighter-rouge, allowing you to customize your CSS appropriately.
As for avoiding splitting the block: That is not possible with kramdown. However, you could implement a custom syntax highlighter that knows how to do this.