Asciidoc archetype for Hugo - hugo

I just started to use Hugo and I want to use it with Asciidoc.
The default "archetype" (i.e. template) is in markdown (default.md). Anyone knows how to get an archetype for Asciidoc?
In particular, shall I rename to default.adoc?
This is how the default archetype looks like.
default.md
---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
date: {{ .Date }}
draft: true
---

It shall be kept as default.md.
This only represents the font-matter that will be on top of the files and is not linked to any type (i.e. MarkDown or AsciiDoc, it will be the same).

Related

2D array in YAML

I've a helm chart with attribute 2darrayIPs. This attribute takes value from values.yaml file which inturn is given via helm installation command
helm-chart/templates/main.yaml
2darrayIPs: {{ .Values.2darrayIPs }}
helm-chart/values.yaml
2darrayIPs: [[]] -- empty array, this value is given via installation command
I'm passing 2d array via helm command while installing helm chart.
helm install ..... -f val.yaml
val.yaml
2darrayIPs:
- - 1.1.1.1
- 2.2.2.2
- - 3.3.3.3
- 4.4.4.4
I'm getting this error while installing helm chart:
Error: YAML parse error on templates/main.yaml: error converting YAML to JSON: yaml: did not find expected ',' or ']'
If I give one array as given below, the installation is successful but in my logs I get a single array with only one value instead of two:
[[1.1.1.1 2.2.2.2]]
val.yaml
2darrayIPs:
- - 1.1.1.1
- 2.2.2.2
Where am I going wrong?
If your templates are trying to write out something more complex than a simple string, the default {{ .Values.name }} serialization is something Go-native that's not especially useful. Helm includes a toJson template function, and also an undocumented toYaml, which can write these out in more useful formats.
# as an array of arrays, in JSON syntax
2darrayIPs: {{ .Values.2darrayIPs | toJson }}
# as an array of arrays, in expanded YAML syntax
# (identical to the previous, but `helm template` output will be
# easier to read)
2darrayIPs: {{- .Values.2darrayIPs | toYaml | nindent 2 }}
# as a YAML-encoded string; for example in a ConfigMap
2darrayIPs: |-
{{ .Values.2darrayIPs | toYaml | indent 2 }}
This is valid yaml. If possible, you should raise an issue on the repository of the yaml parser used here. In the meantime, Yaml is a superset of JSON, so you can use plain JSON 2D arrays:
2darrayIPs: [["1.1.1.1","2.2.2.2"]]

adding a page bundle with `hugo new`

I can add a new page with hugo new posts/new-page. But I want to add a page bundle. None of the following work
hugo new posts/2021/10/new-page creates a single new-page.md
hugo new posts/2021/10/new-page/ does the same as above
hugo new posts/2021/10/new-page/index.md works, kind. It creates index.md in the correct path and populates index.md with the archetypes/default.md except, it set the title to index instead of new page
so, how can I add a page bundle with hugo new
You can achieve that using Archetypes , quoting from the docs:
Since Hugo 0.49 you can use complete directories as archetype templates.
in the archetypes/ folder create a new folder named post-bundle/
inside it create a new file index.md
archetypes/post-bundle/index.md :
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
Then to create a page bundle:
hugo new --kind post-bundle posts/new-page
Notice: I don't think the approach you're doing to set the date in the url is correct , the above method will give a post with the following Permalink : example.com/posts/new-page you can then do the following to get the desired Permalink:
config.toml :
[permalinks]
posts = '/:year/:month/:title/'
In support of Mossab's answer...
a page bundle has three categories:
Branch,
headless
and leaf.
So if you made a file _index.md - it's a Branch bundle, off-the-bat. So viola that's how you make it with hugo new.
If you want a headless bundle, I believe you first need a leaf bundle, and then add:
headless = true to the front matter.
If you want a lead bundle you create an index.md file at any directory level.
So, I believe my point in this is, the way you do this is:
hugo new _index.md
Or
hugo new index.md
and if you want it headless, you use an archetype with the front matter (as Mossab desribes).
Please let me know if I'm possibly misunderstanding something.

Can't use template variable of type string where a string literal would be allowed?

It seems I cannot invoke .Resources.GetMatch with a template variable of type string, though I can invoke it with a string literal. I know I can invoke it with . in a with block, but would like to know why this code doesn't work.
Main template invokes partial with a second argument stuffed into .Scratch:
single.html
...html
<div >
<p>Feature image:</p>
{{ .Scratch.Set "arg1" .Params.image}}
{{ partial "local-image.html" . }}
<p>End feature image:</p>
</div>
Partial tries to retrieve the scratch argument and retrieve the corresponding page resource object:
{{ $srcPath := (.Scratch.Get "arg1") }}
{{ printf "debug type %T, value %#v" $srcPath $srcPath}}
{{ .Resources.GetMatch $srcPath }}
Hugo build error:
ERROR 2020/11/24 00:28:34 Failed to render pages: render of "page" failed:
execute of template failed: template: _default/single.html:67:7: executing "main" at <partial "local-image.html" .>:
error calling partial: "C:\Users\xyz\src\hugo-blog\themes\hugo-theme-bootstrap4-blog\layouts\partials\local-image.html:5:23": execute of template failed:
template: partials/local-image.html:5:23: executing "partials/local-image.html" at <$srcPath>:
invalid value; expected string
If I comment out the failing line so I can see the preceeding debug output,
{{ $srcPath := (.Scratch.Get "arg1") }}
{{ printf "debug type %T, value %#v" $srcPath $srcPath}}
{{/* .Resources.GetMatch $srcPath */}}
Build succeeds, and page renders this:
Feature image:
debug type string, value "IMG_20200404_164934.jpg"
End feature image:
So the puzzle here is why .Resources.GetMatch complains about $srcPath when the latter is demonstrably of type string.
(Yes, I know it would be more colloquial to pass multiple arguments into a partial in a dict, but I was running into similar errors extracting values out in the partial, so came up with the above more concise example.)
I rewrote my problematic code and came up with a workable solution, but I never did discover exactly where I was going wrong above (it remains reproducible for anyone who would like to point out exactly where I did go wrong).
To close this thread with something like an acceptable answer, here's what I did.
Maybe it will help some future wanderer...
Basically,
stuff all the arguments into a dict where the partial is invoked.
at the top of the partial, save value of . (e.g in a nicely-named local $args or $argv)
wherever you need a particular argument value, it's readily available in $args.xyzzy
I don't know why this simple and effective pattern eluded me yesterday, I see lots of similar suggestions around the web today...
single.html
...html
<div >
<p>Feature image:</p>
{{ partial "local-image.html" (dict "page" . "arg1" .Params.image) }}
<p>End feature image:</p>
</div>
Then, to retrieve or use these arguments in the partial:
{{ $args := . }}
. . .
{{ $srcPath := $args.arg1 }}
{{ printf "debug type %T, value %#v" $srcPath $srcPath}}
{{ .Resources.GetMatch $srcPath }}
Build succeeds, and page renders this:
Feature image:
debug type string, value "IMG_20200404_164934.jpg"
"IMG_20200404_164934.jpg"
End feature image:
Q.E.D.

Ansible create directories from a list

I want to create some directories from a list I have in my vars/main.yml.
- app_root:
network_prod: "/var/www/prod/network/app"
database_prod: "/var/www/prod/db/app"
My tasks/main.yml so far has this:
- name: Create application directory structure
file:
path: "{{ item }}"
state: directory
mode: 755
with_items:
- app_root
but doesn't work. I thought this could be achieved using with_dict and I also tried:
- name: Create application directory structure
file:
path: "{{ item.value }}"
state: directory
mode: 755
with_dict:
- app_root
but I got: fatal: [vagrant.dev] => with_dict expects a dict.
I've read all about looping-over-hashes, but this doesn't seem to work.
The reason I'm using this notation is because I use these variables elsewhere as well and I need to know how to call them.
I personally find it a bit easier to convert yaml to json to make sure I'm understanding it properly. Take your example:
- app_root:
network_prod: "/var/www/prod/network/app"
database_prod: "/var/www/prod/db/app"
What you have here is not a list, but a nested dictionary. If you converted this to json it would look like this:
[
{
"app_root": {
"network_prod": "/var/www/prod/network/app",
"database_prod": "/var/www/prod/db/app"
}
}
]
In order to loop through this in Ansible you would need to dereference two levels of a dictionary, the first being app_root and the second being the path elements. Unfortunately I don't think Ansible supports looping through nested dictionaries, only through nested loops.
Your best bet is probably to redo the way you're defining your paths so that you're not creating as complex a data structure. If all you're doing in this case is iterating over a list of paths in order to ensure the directories exist then I'd suggest something like this in your vars/main.yml file:
network_prod: "/var/www/prod/network/app"
database_prod: "/var/www/prod/db/app"
app_root:
- network_prod
- database_prod
Then you can have a task like this:
file: path={{ item }}
state=directory
with_items: app_root
In vars/main.yml, try removing the dash in front of app_root.
app_root:
network_prod: "/var/www/prod/network/app"
database_prod: "/var/www/prod/db/app"
I think that the approach with with_dict was correct and I believe that the only issue here is the dash - in front of app_root variable. Instead of:
- name: Create application directory structure
file:
path: "{{ item.value }}"
state: directory
mode: 755
with_dict:
- app_root
It should be:
- name: Create application directory structure
file:
path: "{{ item.value }}"
state: directory
mode: 755
with_dict: app_root
See the difference on the way the variable app_root is passed to with_dict.
A dash in YAML starts a list and the elements are not treated as variables but as literals, think of it as if you were passing an immutable string 'app_root' to with_dict (not exactly true but it helps me to think it this way) so when_dict fails to parse it because it is given a list instead of the expected dictionary. However, without a dash, with_dict is populated with the variable app_root instead and it will parse it without issues.

How to add a new hugo static page?

From the "getting started" section it seems this should work, but it doesn't.
hugo new site my-site
hugo new privacy.md
hugo server --watch --includeDrafts
curl -L localhost:1313/privacy/index.html
# 404 page not found
curl -L localhost:1313/privacy.html
# 404 page not found
curl -L localhost:1313/privacy/
# 404 page not found
How can I add a new page?
This is the best tutorial how to create static "landing pages" on Hugo: https://discuss.gohugo.io/t/creating-static-content-that-uses-partials/265/19?u=royston
Basically, you create .md in /content/ with type: "page" in front matter, then create custom layout for it, for example layout: "simple-static" in front matter, then create the layout template in themes/<name>/layouts/page/, for example, simple-static.html. Then, use all partials as usual, and call content from original .md file using {{ .Content }}.
All my static (landing) pages are using this method.
By the way, I'm not using hugo new, I just clone .md file or copy a template into /content/ and open it using my iA Writer text editor. But I'm not using Hugo server either, adapted npm-build-boilerplate is running the server and builds.
Just tested OK with this on Hugo 0.13:
hugo new site my-site
cd my-site
hugo new privacy.md
hugo server -w -D
curl -L localhost:1313/privacy/
Note: You have to either use a theme or provide your own layout template to get something more than a blank page. And of course, some Markdown in privacy.md would also make it even nicer.
See http://gohugo.io/overview/introduction for up-to-date documentation.
I had a similar requirement, to add static page (aboutus in this case). Following steps did the trick,
Created an empty file content/aboutus/_index.md
Created aboutus.html page layouts/section/aboutus.html
Make you have some default frontmatter set in archetypes/default.md
# archetypes/default.md
+++
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
+++
And the single layout in layouts/_default/single.html to render some variable or content
# tags to render markdown content
<h1>{{ .Title }}</h1>
<p>{{ .Content }}</p>
<span>{{ .Params.date }}</span>
Now type hugo new privacy.md which will create a new page on the following directory in content/privacy.md
Take "About" as example:
# will create content/about.md
hugo new about.md
Edit about.md and add the last 2 lines, the metadata/front matter looks like:
title: "About"
date: 2019-03-26
menu: "main"
weight: 50
That should work.

Resources