diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e26dfe..7096176 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "editor.defaultFormatter": "HookyQR.beautify" +} diff --git a/blog/config.toml b/blog/config.toml index 71a288b..b36a907 100644 --- a/blog/config.toml +++ b/blog/config.toml @@ -6,6 +6,7 @@ languageCode = "en" DefaultContentLanguage = "en" enableInlineShortcodes = true footnoteReturnLinkContents = "^" +description ="Tech blog showcasing Python, Machine-Learning, Vue, Homelab and other technologies to try at home." [menu] @@ -47,3 +48,7 @@ url = "https://commento.panaetius.co.uk/js/commento.js" [imaging] resampleFilter = "Lanczos" + +[outputs] + home = ["HTML", "RSS", "JSON"] + page = ["HTML", "RSS"] diff --git a/blog/content/authors/daniel-tomlinson/_index.md b/blog/content/authors/daniel-tomlinson/_index.md index cd1d3e0..0c3f817 100644 --- a/blog/content/authors/daniel-tomlinson/_index.md +++ b/blog/content/authors/daniel-tomlinson/_index.md @@ -1,8 +1,9 @@ --- -name: "Daniel Tomlinson" +name: +- "Daniel Tomlinson" images: - "daniel-tomlinson.png" -twitter: "" +twitter: "dmot7291" --- Some text here. diff --git a/blog/content/authors/new-authors/_index.md b/blog/content/authors/new-authors/_index.md new file mode 100644 index 0000000..ecfa458 --- /dev/null +++ b/blog/content/authors/new-authors/_index.md @@ -0,0 +1,9 @@ +--- +name: +- "New Authors" +images: +- "new-author.png" +twitter: "dmot7292" +--- + +Some text here. diff --git a/blog/content/authors/new-authors/new-author.png b/blog/content/authors/new-authors/new-author.png new file mode 100644 index 0000000..31a4ba2 Binary files /dev/null and b/blog/content/authors/new-authors/new-author.png differ diff --git a/blog/content/homepage/index.md b/blog/content/homepage/index.md deleted file mode 100644 index 01ffa31..0000000 --- a/blog/content/homepage/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -headless : true ---- diff --git a/blog/content/images/first_post.svg b/blog/content/post/first_post/images/banner.svg similarity index 100% rename from blog/content/images/first_post.svg rename to blog/content/post/first_post/images/banner.svg diff --git a/blog/content/post/first_post.md b/blog/content/post/first_post/index.md similarity index 86% rename from blog/content/post/first_post.md rename to blog/content/post/first_post/index.md index fc84758..eb60724 100644 --- a/blog/content/post/first_post.md +++ b/blog/content/post/first_post/index.md @@ -1,7 +1,8 @@ --- title: "First Post" +description: "The first post testing Hugo out for its markdown features and commento integration." date: "2020-05-04T02:14:50+01:00" -images: ["/images/first_post.svg"] +images: ["images/first_post.svg"] draft: true authors: ["Daniel Tomlinson"] tags: ["Introduction"] diff --git a/blog/content/post/second_post/images/banner.svg b/blog/content/post/second_post/images/banner.svg new file mode 100644 index 0000000..a05cc0e --- /dev/null +++ b/blog/content/post/second_post/images/banner.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blog/content/post/second_post.md b/blog/content/post/second_post/index.md similarity index 85% rename from blog/content/post/second_post.md rename to blog/content/post/second_post/index.md index 3dff399..d330caf 100644 --- a/blog/content/post/second_post.md +++ b/blog/content/post/second_post/index.md @@ -1,9 +1,11 @@ --- title: "Second Post" date: "2020-05-05T02:14:50+01:00" -images: ["/images/data_report.svg"] +images: ["images/data_report.svg"] draft: true -authors: ["Daniel Tomlinson"] +authors: +- "Daniel Tomlinson" +- "New Authors" tags: ["Introduction"] --- @@ -48,3 +50,9 @@ def flask(): ## Vimeo Simple Shortcode {{< vimeo_simple 48912912 >}} + +--- + +## Test img shortcode + +{{< img "images/banner.svg*" >}} diff --git a/blog/hugolayout.md b/blog/hugolayout.md index fc72c72..d6ddda1 100644 --- a/blog/hugolayout.md +++ b/blog/hugolayout.md @@ -4,6 +4,10 @@ There are a lot of template types: . ### Templates +The layout order is important in Hugo. You can use this to see all the different template pages you can create, and where they should go. It will show the order of preference when looked up. + + + #### Base template @@ -42,8 +46,71 @@ Content from markdown files should go in `./content/post`. No `index.md` file is #### List pages + + +You can define a list page for taxonomies for example. + +A list template is a page that houses a list of things. These could be articles, or taxonomies, or even articles under a taxonomy. + +To do this for authors, create a `list.html` in `./layouts/authors`. + +This `list.html` should define a `main` block, and what you want the page to look like when this is visited. If you create a `daniel-tomlinson` author, this is the page that will be used to display this author. + +This `list.html` will be used for the endpoint `/authors`, as well any actual authors `/authors/daniel-tomlinson`. If you want to display a different template for the `/authors`, say a list of all authors, then look at term pages. + +To display content, create an `_index.md` file in `./content/authors/daniel-tomlinson`. + +For a _branch_ bundle you need an `_index.md` at the lowest branch for the tree to be navigable. You can optionally put one at other points along the chain if you want metadata in there as well. E.g `./layouts/authors` can have an `_index.md`, but it doesn't need one. You would need one in `./layouts/authors/daniel-tomlinson` in order for the tree to work. + +This `_index.md` is used for metadata, and any content you want to be displayed. This content can be displayed in the `list.html` with + +```hugo +
+ {{ $term.Content }} +
+``` + +#### Term pages + +In addition to list pages, you might want to display a different page if someone visits `panaetius.io/authors` to the page if you visited an actual author. With just a `list.html` in `./layouts/authors`, this `list.html` will be used for the `/authors` endpoint. + +To display different content, you should create a `terms.html`. + +You can list all pages under this taxonomy in this `list.html` with the variable `{{ range .Data.Pages }}`. + +You can also list all site variables, for example you can have a `/tags` endpoint and reference and display all the tags, even though they're not physically rendered in any other page: + +```hugo + +``` + +If you create a `terms.html` in `./layouts/authors` you can then access all pages under this bundle. To Display and link to the author names pages themselves: + +```hugo +
+
    + {{ range .Data.Pages }} + {{ $page := . }} + {{ range .Params.name }} +
  • {{ . }}
  • + {{ end }} + {{ end }} +
+
+``` + +For more things you can do with taxonomy or term pages, see . + ### Difference between \_index.md and index.md (Bundles) +A really good resource explaining these concepts, and going into more detail on resources in Hugo is: + @@ -74,10 +141,65 @@ An example of using headless bundles to reference pages in a bundle and display For example, you can create `./content/images` with an `index.md` that has `headless: true`. The contents of `./content/images` won't be published, but they will be accessible to other resources. You could reference these images locally in another content type. E.g `./content/posts/page.md` could reference one of these images. +```text +./content/images +├── data_report.svg +├── first_post.svg +├── homepage.svg +└── index.md +``` + +These can be referenced in front matter with `images: ["/images/first_post.svg"]` in the files: + +```text +./content/post +├── first_post.md +└── second_post.md +``` + +##### index.md + +Essentially: `index.md` is used to create _bundles_ of content. If you're writing a collection of single posts, you can create a folder for each one in `./content/posts/`: + +```text +./content/post +├── first_post +│ ├── images +│ │ └── banner.svg +│ └── index.md +└── second_post + ├── images + │ └── banner.svg + └── index.md +``` + +The `index.md` should contain all the markdown for the page. Because it is called `index.md`, it won't create a new endpoint it will be referenced and displayed at `/post/first_post`. + +You can then create `single.html` and custom views like `card.html` in `./layouts/post` for this content. + +In the `single.html` in `./layouts/post/` we can use the following to refer to the banner image for each post: + +```html +{{- with .Resources.Match "images/banner.svg" -}} {{ range . }} +
+
+ {{ $page.Title }} +
+
+{{- end -}} {{- end -}} +``` + #### Branch bundles These are used in list pages. +If you have a taxonomy, you need a + If you have an `_index.md` then all markdown files alongside it will render as a list template, and not as a single page template: . ##### Use 1: Taxonomy metadata @@ -96,6 +218,112 @@ You can place markdown content inside this `_index.md` file to be displayed on t ``` +### Using bundles to reference files relative to its own post + +We've seen how we can use bundles to access images relative to its own page. (I.e a banner image that is shown automatically in the `single.html`) + +We can extend this and use Resources and the page's front matter to include anything in these bundles, and have them available locally. + +This link explains it in detail: . + +### Shortcodes + + + +We can use shortcodes to define snippets of html that we can reference in the markdown. This will let us dynamically insert content, such as an image or even a link to a file. + +#### Displaying an image + +The following is a shortcode template that can be used to display an image: + +```html +{{ $img := $.Page.Resources.GetMatch (.Get 0)}} +
+ (.Get 1) +
{{.Get 1}}
+
+``` + +This shortcode expects two arguments (by using `.Get`). The first is the name of the image which `Resources` will use to find the file, and the second is a caption to go alongside it. + +This shortcode should go in `./layouts/shortcodes/` and we will call it `img.html`. + +Then, in your markdown you can reference it using: + +```markdown +{{< img "*overcooked-dough*" "Those cupcakes are way overcooked!" >}} +``` + +It will look for the image called `overcooked-dough` and use the caption we provided. + +#### Rendering a list of files + + + +You can use metadata in your front matter to reference and define resources: . + +We can create a `manifest.html` in `./layouts/shortcodes`: + +```html + +``` + +Then in the markdown we reference it like: + +```markdown +title: "Bogus Application" +date: 2018-01-10T10:36:47-05:00 + +resources: + +- src: 'documents/guide.pdf' + name: Instruction Guide + params: + ref: '90564568' +- src: 'documents/checklist.pdf' + name: Document Checklist + params: + ref: '90564572' +- src: photo_specs.pdf + name: Photo Specifications + params: + ref: '90564687' +- src: 'documents/payment.docx' + name: Proof of Payment + +# Now our shared values + +- src: '\*.pdf' + params: + icon: pdf +- src: '\*.docx' + params: + icon: word + +{{< manifest >}} +``` + +This will look for all files in (for example) `./content/post/first_post/documents` and display them in a list. + +Note the metadata. When using this resources in the front matter although the items in the list are all lower case in the template they will be referenced by their capital letter. Eg `.Name` and `.Title`. + +name is _overwriting_ the filename. If you specify name you're setting a new name for Hugo. It will match with `.Match` and `.GetMatch` against this new name. This is useful if your filenames are ugly, or automatically generated by something and you want to display them differently. + +Title is using the same name as name (confusing!). + +params allows you to specify additional custom information about the file. Here we're using a wildcarded `src` to find `.pdf` files and setting an `icon` parameter for Font Awesome. + +An example of this live is here: . + ### Blocks You can define blocks in a base template and put content in it. Then you can overwrite these blocks in other templates. @@ -132,9 +360,237 @@ You can also use partials to return a value of any type. For example, you could You can access `site.RegularPages` in the partial to access a parameter in each page, and display them: . -### Adding content +### Render functions -There are a lot of template types: . +In a template file, can grab content (with the `Range` function): -- Adding single pages (about etc) -- Adding content (blog posts) - index + html files +```html +
+ {{ range after 1 (where .Site.RegularPages "Type" "in" + .Site.Params.mainSections) }} +
+ {{ .Render "card" }} +
+ {{ end }} +
+``` + +And pass it off to a Render function which references a view. In this case `card` is a template in `./layouts/_default/card.html`. + +If you want a different view depending on the content being rendered, you should create the `card.html` for each content you want it to be applied to. + +So if we wanted to use `card.html` for post and it be different to the default view, we should create `./layouts/post/card.html`. + +Hugo knows the content type and location when using a render, and will use it if it exists, and default to the view in `./layout/_default` if not. + +This only works in a list context - i.e in your `html` template you should use `range` or some other command that gets you a list context. + +#### Not using render functions + +If you don't need to use render functions, say you want to grab the content and not pass it to a view html template you can always do it inline: + +```html +{{- range first 1 (where .Site.RegularPages "Type" "in" +.Site.Params.mainSections) -}} {{ $page := . }} +
+
+ {{- with .Resources.Match "images/banner.svg" -}} {{ range . }} {{- $image + := . -}} + + {{ $page.Title }} + + {{- end -}} {{- end -}} +
+
+
+ {{ $page.Date.Format "January 2, 2006" }} +
+

{{ $page.Title }}

+ +
+ {{ $page.Summary }} +
+
+
+{{- end -}} +``` + +### Chaining multiple Range or With commands in html templates + +If you need to use multiple `range` and `with` statements in the `html` templates, you can use variables in Hugo to store the reference to be used later on in the chain: + +```hugo +{{- range first 1 (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) -}} + {{ $page := . }} +
+
+ {{- with $page.Params.images -}} + {{- $images := . -}} +``` + +### html snippets for templates + +#### Get authors from front matter + +`{{ .Params.authors }}` + +#### Iterate through a list + +```hugo +{{ range $term.Params.name }} +{{ end }} +``` + +#### Get n'th item + +`{{ index $term.Params.name 0 }}` + +#### Get the corresponding page in a bundle from an author + +You can access paramters in other pages from a different page by using `$.Site.GetPage` to find the page. You can find the page using front matter from the current page you are in as a variable. + +```hugo +{{- with $.Site.GetPage (printf "/authors/%s" (. | urlize)) -}} +{{- $term := . -}} +``` + +You can get the permalink of this page to use in the html + +`{{ $term.RelPermalink }}` + +We use this to get the image of an author in a branch bundle. + +#### Get a resource (image etc) from a parameter + +`{{- with .Resources.GetMatch (index $term.Params.images 0) -}}` +`{{ end }}` + +You can resize the image + +`{{- $image := .Resize "64x" -}}` + +And then use the permalink to display in html + +`{{ $image.RelPermalink }}` + +#### Set parameter + +`{{ $term := . }}` + +#### Access all pages in a branch bundle + +If you're writing a `terms.html` you can find all page in the bundle with + +```hugo +{{ range .Data.Pages }} +{{ end }} +``` + +### Creating a search index using Scratch + + + + +You can dynamically create a whole index of all blog posts or any content in a json file with Hugo. + +You should first add `JSON` to the `[outputs]` stanza in your `config.toml` file: + +```toml +[outputs] + home = ["HTML", "RSS", "JSON"] + page = ["HTML", "RSS"] +``` + +Then in `./layouts/_default` create an `index.json` file. + +We can utilise the Hugo command scratch, which creates a temporary scratch pad to store variables, to create a json object for the whole site: + +```json +{{- $.Scratch.Add "index" slice -}} +{{- range .Site.RegularPages -}} + {{- $.Scratch.Add "index" (dict "title" .Title "subtitle" .Params.subtitle "description" .Params.description "tags" .Params.tags "images" .Params.images "content" .Plain "permalink" .Permalink) -}} +{{- end -}} +{{- $.Scratch.Get "index" | jsonify -}} +``` + +### SEO + +To optimise Hugo for SEO we can follow this guide: . + +#### Structured data + +Structured data is provided in your html base template that allows Google to know more about the content it is showing. Structured data shows the ratings in a review, or the calories in a recipe on the card itself in the search results. + +There is a standard from Schema that shows all possible rules you can use: . + +Google also has documentation for certain types. A blog post or article can be found here: . + +We use this guide to set the structured data: for a Hugo article. + +Create a `schema.html` file in `./layouts/partials/`. + +An example file for an article is: . + +#### Generic meta tags + +The following should go in your `` block: + +```html + + + +``` + +#### Title + +You should set a title for your pages. + +You should have a unique title for each page. This will be used to create a dynamic title for SEO like `My first blog post | panaetius.io`. + +```hugo + +{{ $scratch := newScratch }} +{{ with .Params.Title }} +{{ $scratch.Set "title" . }} +{{ $scratch.Add "title" " | " }} +{{ end }} +{{ $scratch.Add "title" .Site.Title }} + + + + + + +``` + +If the `Title` has been set on a page, it will use this then append the site title, else it will just the site title. + +#### Description + + + +You should set a description on your posts and other pages. + +This description should be no more than 155 characters and a few sentences. It should succintly and accurately describe your page and its content. E.g if you're writing a tutorial you would say so explicitly and give a brief idea of what it is. + +```hugo + +{{ if .Description }} +{{ $scratch.Set "description" .Description}} +{{ else if .Site.Params.description }} +{{ $scratch.Set "description" .Site.Params.description }} +{{ end }} + + + + + +``` diff --git a/blog/themes/hugo-theme-chunky-poster b/blog/themes/hugo-theme-chunky-poster index 9f430f3..a2b62a3 160000 --- a/blog/themes/hugo-theme-chunky-poster +++ b/blog/themes/hugo-theme-chunky-poster @@ -1 +1 @@ -Subproject commit 9f430f33f81f97d1604a2a304cbbfadc72389507 +Subproject commit a2b62a370ba07825ad3c7a915de24a78ed35e6f2 diff --git a/tasks.todo b/tasks.todo index 05bb74e..3b0626c 100644 --- a/tasks.todo +++ b/tasks.todo @@ -14,23 +14,30 @@ Tasks: ✔ Add image to homepage + document @done (5/5/2020, 4:09:20 AM) ✔ Add image to post + document @done (5/5/2020, 7:32:50 PM) + Colour: + ☐ Add colour to default `` like Forestry