Including source files from a repo in HUGO posts - hugo

I'm setting up a blog with HUGO, as a commented code repo, and I'm including source files right from the repos on the posts.
I've been able to get it to a working condition and want to improve it but I'm stuck.
What I've done
There's a .gitignore'd repos dir inside the HUGO site root, that holds the source code repos.
There's a getSourceFile.html shortcode:
{{ with .Get 0 }}
<pre><code>{{ readFile . }}</code>
<span class="source-footer">{{.}}</span>
</pre>
{{ end }}
Then, in the post I can use the shortcode like so:
#### Base/EntityTypeConfiguration.cs
Estas clases permiten manejar una clase de configuraciĆ³n por cada clase del modelo...
{{< getSourceFile "repos/EFCoreApp/src/EFCore.App/Base/EntityTypeConfiguration.cs" >}}
and I get this:
Which is pretty nice, since I don't have to copy and paste code, it's 100% up to date and I am sure it compiles.
But this is where I'm stuck!
What I would like to do
1) Setting up the repo root in the front matter so the shortcode is simpler to use, like so:
{{< getSourceFile "src/EFCore.App/Base/EntityTypeConfiguration.cs" >}}
2) Being able to pass the language as a parameter to the shortcode to use it in the highlighting feature, something like so (this does not work):
{{< getSourceFile "src/EFCore.App/Base/EntityTypeConfiguration.cs" "csharp" >}}
getSourceFile.html:
{{ with .Get 0 }}
```{{.Get 1}}
<pre><code>{{ readFile . }}</code>
<span class="source-footer">{{.}}</span>
</pre>
```
{{ end }}
Or better yet, infer it from the file extension! ;-)
I think it shouldn't be too difficult but this is my first experience with Hugo, Go and the Templates, so, Could someone help me with this, please?
Thanks in advance.

I finally got the answer in HUGO's dicussion forum, so I just wanted to post it here to finish the question.
This is the final shortcode:
{{ $file := .Get 0 }}
{{ $repoFilePath := printf "%s/%s" $.Page.Params.reponame $file }}
{{ $repoFile := printf "repos/%s" $repoFilePath }}
{{ $fileExt := replace (index (findRE "(\\.)\\w+$" $file) 0) "." "" }}
<pre><code class="language-{{ $fileExt }}">{{ readFile $repoFile }}</code>
<span class="source-footer">{{ $repoFilePath }}</span>
</pre>
And this even solves the language highlighting from the file extension.

Related

Issue with double-escaped entities in the link

I am getting double-escaped entities in the link in a post. For example, a link What's the difference becomes What&rsquo;s the difference.
The problem is similar to this https://discourse.gohugo.io/t/solved-why-is-page-title-getting-double-escaped-entities/14935 however it didn't help me solve this.
Why is this happening? How do I solve it?
The code for the blog is available here - https://github.com/desecho/blog
Your renderhook:
<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank"{{ end }}>{{ .Text }}
Change it to:
<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank"{{ end }}>{{ .Text | safeHTML }}
That should do the trick.
Now, the reason why is, well Turtles all the way down, but, realize that Hugo is working with a Markdown engine "goldmark" and you have your config set "unsafe=true", but even beyond that you now have HUGO creating/building with your render hook back to markdown. Not clear to me how they all work together, but their is empirically a lot of back and forth...
So... The above should be fine.
Please test and let me know.
(Providing your code was key, and probably a note for your future-self, if the above resolves your problem, of that).
Bien suerte!

How can you get the full path of a page resource in Hugo?

I have some posts in Hugo with page resources that are SVG files that I want to include inline in the resulting HTML. For example, here's a typical folder structure:
content
+-- posts
+-- somepost
+-- index.md
+-- diagram.svg
In the post, I'd like to include the content of diagram.svg inline as part of the resulting HTML. Reading through another related question, I created a shortcode to do that that looks like this:
{{- readFile (.Get 0) | safeHTML -}}
However, this means that I need to provide the full path to the SVG resource, which results in this in my markdown:
{{< readsvg "content/posts/somepost/diagram.svg" >}}
Ideally, I would like the shortcode to find the page resource so that the markdown can be simplified to:
{{< readsvg "diagram.svg" >}}
If I use the page resource functions, I can get the resource itself by doing: {{ $svg := $.Page.Resources.GetMatch (.Get 0) }} but the resulting file name is relative to the resource bundle while readFile needs it to be relative to the top of the project. How can I get the full path of the resource so that I can pass it to readFile?
I tried to use absURL to do that but this doesn't work as I have custom URLs on posts.
Thanks to ruddra for pointing me in the right direction, the full answer that worked was:
{{ $svgFile := (path.Join (path.Dir .Page.File.Path) (.Get 0)) }}
{{- readFile $svgFile | safeHTML -}}
If you want more flexibility in how you specify the resource in the markdown, you can add a resource match to that solution:
{{ $svgRes := .Page.Resources.GetMatch (.Get 0) }}
{{ $svgFile := (path.Join (path.Dir .Page.File.Path) $svgRes) }}
{{- readFile $svgFile | safeHTML -}}
I think the svg file should be inside static directory. But still if you want to put it in same directory as the markdown files, probably you can use .File.Dir in the custom shortcode. Like this:
{{ $svgFile := print (.Page.File.Path) (.Get 0) }}
{{- readFile $svgFile | safeHTML -}}

Hugo post directory appearing on homepage, but not posts

For my blogdown-created website (using the Xmin theme), the posts directory - from which I can view individual posts - appears on the homepage, instead of individual posts.
https://joshuamrosenberg.com/
This seemed to happen after updating to the lastest version of Hugo. The source for my website is here. I'm a bit puzzled about what to do: do you have any advice?
This is due to a breaking change in Hugo 0.57.0, and I have fixed the issue in the latest version of the XMin theme. Basically you need to replace
{{ range (where .Data.Pages "Section" "!=" "") }}
with
{{ $pages := .Pages }}
{{ if .IsHome }}{{ $pages = .Site.RegularPages }}{{ end }}
{{ range (where $pages "Section" "!=" "") }}
in the template file layouts/_default/list.html.

Symfony2 - Checking if an image type exists

I've been following an earlier post to check if an asset exists, which works great when using specific filenames.
Symfony2 and Twig - Check if an asset exists
However instead of checking for a specific image filename, how do you check for an image type? (all files with the .jpg extension)
Example: *.jpg (which doesn't work neither does .jpg)
{% if asset_exists('/images/*.jpg') %}
<div class="entry-thumbnail">
<img width="230" height="172" src="{{ asset(['images/', post.image]|join) }}" class="" alt=""/>
</div>
{% endif %}
As soon as you are using:
{{ asset(['images/', post.image]|join) }}`
Why not using:
{% if asset_exists(['images/', post.image]|join) %}
Tip: replace ['images/', post.image]|join by using the concat operator ~: 'images/' ~ post.image
You'd have to modify the Twig Extension and replace !is_file($toCheck) with count(glob($toCheck)) < 1
glob function (php.net)

In jinja2 on Google App Engine, how can I (easily) build a URL based on a route name with arguments?

If I construct a jinja environment as follows:
jinja_environment = jinja2.Environment (
loader=jinja2.FileSystemLoader ((os.path.dirname (__file__), 'templates')), extensions=[])
jinja_environment.globals['url_for'] = webapp2.uri_for
In my templates, I can build simple URLs from a route name when the route does not define any arguments:
{{ url_for('user_home') }}
However, when the route contains an argument as defined by a string such as /invoice/<:\d+>, I am unable to pass any arguments. Calling it in all the following ways fails, with a KeyError "Missing argument "0" to build URI.":
{{ url_for('invoice') }}
{{ url_for('invoice', args=['123']) }}
{{ url_for('invoice', kwargs={'__0__':'123'}) }}
{{ url_for('invoice',_request=None, args=['123'],kwargs={'__0__':'123'}) }}
Existing examples for this seem to be out of date--at least I haven't been able to make them work. What am I missing?
Route('/invoice/<invoice_id>/', handler=invoice_handler, invoice_id='something')
{{ url_for('invoice', invoice_id=123) }}
You can try the above, Jinja is expecting the named parameter you defined your handler.
I think just {{ url_for('invoice', 123) }} should work.

Resources