Skip to content

Commit

Permalink
Use internal Zola translation feature and documented usage of transla…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
awinterstein committed Dec 4, 2024
1 parent 2656eaa commit 35d077a
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 126 deletions.
59 changes: 52 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ Check out the [live demo of the example project](https://awinterstein.github.io/
## Features

- Project types and skills taxonomies
- Dark / light modes (with syntax highlighting depending on selected theme)
- Customizable navbar links
- Automatically selected dark / light modes (with syntax highlighting depending the mode)
- Search functionality supporting `Meta` + `K` shortcut
- Social links (github, gitlab, twitter, linkedin, email)
- Pagination
- Sidemenu menu with sections links
- Table of content (2 levels and currently viewed part highlighted)
- Multilingue
- Multilingual
- Error 404 page
- Mobile responsive
- Favicon
- Customizable navbar links
- Customizable footer

## Quick Start

Expand All @@ -44,7 +43,7 @@ theme = "project-portfolio" # The site theme to use.

Create the files `projects.md` and `skills.md` in your `content` directory that are used to show the "Projects" and "Skills" [taxonomies](https://www.getzola.org/documentation/content/taxonomies/). They both need a title and can optionally get a descriptive text that will be shown above the terms of the taxonomy. See the following `projects.md` file as an example:

```toml
```markdown
+++
title = "Projects"
+++
Expand All @@ -67,8 +66,11 @@ The `skills.md` file can be created the same way. The corresponding page will ju

Finally, create the first project page in the `content` directory:

```toml
```markdown
+++
```

```toml
title = "Project Title"
description = "Here is a short description of the project."
date = 2022-05-31 # The date when the project finished
Expand All @@ -81,6 +83,9 @@ top_project = true # Optional parameter to show the project on the projects over
[taxonomies]
projects=["Consumer"] # The category of the project (could be industry, type etc.)
skills=["Thinking", "Hype Technology"] # The skills & technologies used for the project
```

```markdown
+++

The content of the project description page follows here.
Expand All @@ -103,6 +108,16 @@ taxonomies = [
{name = "projects", paginate_by = 5, feed = true},
{name = "skills", paginate_by = 5, feed = true},
]

[translations]
language_symbol = "🇬🇧"
home = "Home"
projects = "Projects"
skills = "Skills"
read_more = "Read More"
skills_technologies = "Skills & Technologies"
main_skills = "Main Skills"
other_skills = "Additional Skills"
```

This would, however, lead to an empty index page. The `config.toml` can be extended by the following configuration parameters for the index page:
Expand Down Expand Up @@ -152,3 +167,33 @@ To overwrite the default footer (copyright notice), extend the `layout.html` tem
Here is my own footer with a <a href="http://example.com">link</a>.
{% endblock %}
```

## Multiple Languages

To enable multilingual support, add the following to the `config.toml` file (adapted to the additional language that you want to support):

```toml
[languages.de]
title = "Projekt-Portfolio"
taxonomies = [
{name = "projects", paginate_by = 5, feed = true},
{name = "skills", paginate_by = 5, feed = true},
]

[languages.de.translations]
language_symbol = "🇩🇪"
home = "Home"
projects = "Projekte"
skills = "Qualifikationen"
read_more = "Weiterlesen"
skills_technologies = "Qualifikationen & Technologien"
main_skills = "Top-Fähigkeiten"
other_skills = "Weitere Fähigkeiten"

[extra]
enable_multilingual = true
```

For the language switching of the theme to work best, it is recommended not to change the names of the taxonomies and to also keep the filenames for all pages of the site the same in all languages. Right now, the theme only supports websites with up to two languages. The default language and one additional language.

Proceed to add translated markdown files.
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h1>
<p class="mb-6">{{ config.extra.index.slogan }}</p>
{% endif %}
{% if config.extra.index.image %}
<img class="rounded-full h-40 w-40" src="{{ config.extra.index.image }}" {% if config.extra.index.image_alt %}alt="{{ config.extra.index.image_alt }}"{% endif %}>
<img class="rounded-full h-40 w-40" src="{{ config.base_url | trim_end_matches(pat='/') | safe }}/{{ config.extra.index.image }}" {% if config.extra.index.image_alt %}alt="{{ config.extra.index.image_alt }}"{% endif %}>
{% endif %}
<div class="flex flex-wrap space-x-4 mt-7">
{% if config.extra.social.codeberg %}
Expand Down
106 changes: 43 additions & 63 deletions templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,43 +1,25 @@
{% import "macros.html" as macros -%}
<!doctype html>
<html lang="{{lang}}">

<html lang="{{ lang }}">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<!-- FAVICON -->
{% if config.extra.favicon.webmanifest %}
<link href="{{ config.extra.favicon.manifest }}" rel=" manifest" />
{% endif %}
{% if config.extra.favicon.favicon_16x16 %}
<link href='{{ config.extra.favicon.favicon_16x16 }}' rel="icon" sizes="16x16" type="image/png" />
{% endif %}
{% if config.extra.favicon.favicon_32x32 %}
<link href='{{ config.extra.favicon.favicon_32x32 }}' rel="icon" sizes="32x32" type="image/png" />
{% endif %}
{% if config.extra.favicon.android_chrome_512 %}
<link href='{{ config.extra.favicon.android_chrome_512 }}' rel="android-chrome" sizes="512x512" />
{% endif %}
{% if config.extra.favicon.android_chrome_192 %}
<link href='{{ config.extra.favicon.android_chrome_192 }}' rel="android-chrome" sizes="192x192" />
{% endif %}
{% if config.extra.favicon.apple_touch_icon %}
<link href='{{ config.extra.favicon.apple_touch_icon }}' rel="apple-touch-icon" sizes="180x180" />
{% endif %}
{% if config.extra.favicon.apple_touch_icon %}
<link href='{{ config.extra.favicon.apple_touch_icon }}' rel="apple-touch-icon" sizes="180x180" />
{% endif %}
{%- if config.extra.favicon.webmanifest %}<link href="{{ config.extra.favicon.manifest }}" rel=" manifest" />{% endif %}
{% if config.extra.favicon.favicon_16x16 %}<link href='{{ config.extra.favicon.favicon_16x16 }}' rel="icon" sizes="16x16" type="image/png" />{% endif %}
{% if config.extra.favicon.favicon_32x32 %}<link href='{{ config.extra.favicon.favicon_32x32 }}' rel="icon" sizes="32x32" type="image/png" />{% endif %}
{% if config.extra.favicon.android_chrome_512 %}<link href='{{ config.extra.favicon.android_chrome_512 }}' rel="android-chrome" sizes="512x512" />{% endif %}
{% if config.extra.favicon.android_chrome_192 %}<link href='{{ config.extra.favicon.android_chrome_192 }}' rel="android-chrome" sizes="192x192" />{% endif %}
{% if config.extra.favicon.apple_touch_icon %}<link href='{{ config.extra.favicon.apple_touch_icon }}' rel="apple-touch-icon" sizes="180x180" />{% endif %}
{% if config.extra.favicon.apple_touch_icon %}<link href='{{ config.extra.favicon.apple_touch_icon }}' rel="apple-touch-icon" sizes="180x180" />{% endif %}

<link href="{{ config.base_url | trim_end_matches(pat='/') | safe }}/css/main.css" rel="stylesheet">

<link rel="stylesheet" type="text/css" href="/syntax-dark.css" media="(prefers-color-scheme: dark)" />
<link rel="stylesheet" type="text/css" href="/syntax-light.css" media="(prefers-color-scheme: light)" />

<title>
{% block title %}
{{ config.title }}
{% endblock title %}
</title>
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
</head>

<body class="dark:bg-gray-700 flex flex-col h-screen justify-between">
Expand Down Expand Up @@ -79,20 +61,9 @@
</div>
<div class="hidden sm:block sm:ml-6">
<div class="nav-links flex space-x-4">
{% for item in config.extra.navbar.items %}
{% if lang == item.lang %}
{% for link in item.links %}
{%if lang == config.default_language %}{% set language_url_part = '' %}{% else %}{% set language_url_part = lang %}{% endif %} {# Empty for default language and language for others. #}
<a href="{{ config.base_url | trim_end_matches(pat='/') | safe }}/{{ link.url }}"
{% if current_path and ((link.url != language_url_part and link.url in current_path) or (link.url | trim_end_matches(pat='/') == language_url_part and current_path | trim_start_matches(pat='/') | trim_end_matches(pat='/') == language_url_part )) %}
class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium" {# Highlight button, if button URL is part of the current path. #}
{% else %}
class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
{% endif %}
>{{link.name }}</a>
{% endfor %}
{% endif %}
{% endfor %}
{{ macros::navbar_button(url="", text=trans(key="home", lang=lang)) }}
{{ macros::navbar_button(url="projects", text=trans(key="projects", lang=lang)) }}
{{ macros::navbar_button(url="skills", text=trans(key="skills", lang=lang)) }}

{% if config.extra.sidebar.items %}
<!-- More ... Button (sidebar) -->
Expand Down Expand Up @@ -180,8 +151,8 @@
</div>
{% endif %}

<!---------------------------- Sidebar Menu ---------------------------->
{% if config.extra.sidebar.items %}
<!---------------------------- Sidebar Menu ---------------------------->
<div id="sidebar"
class="nav-links -translate-x-full flex flex-col pt-6 p-2 text-2xl text-black dark:text-gray-200 bg-gray-200 dark:bg-gray-900 transform top-0 left-0 w-64 bg-white fixed h-full overflow-auto ease-in-out transition-all duration-300 z-30 shadow-2xl">
{% for item in config.extra.sidebar.items %}
Expand All @@ -196,18 +167,33 @@
</div>
{% endif %}

{% if config.extra.enable_multilingue %}

{# Get the non-active language from the languages map. This only works, as long as there are no more than two languages defined. #}
{% for key, item in config.languages -%}
{% set_global other_language = key -%}
{% endfor -%}

<!-- Language change button -->
{% if config.extra.enable_multilingual and current_path %}
<!-- Language change button -->
<div class="flex p-2 ml-4 relative">
<a href="{% if current_path %}{% if lang != config.default_language %}{{ current_path | trim_start_matches(pat='/'~lang) }}{% else %}{{ '/' ~ other_language ~ current_path }}{% endif %}{% endif %}"
{# Get the non-active language from the languages map. This only works, as long as there are no more than two languages defined. #}
{% for key, item in config.languages -%}
{% set_global other_language = key -%}
{% endfor -%}

{% if page %}
{% for item in page.translations %}
{% if item.lang == other_language %}
{% set_global translation_url = item.permalink %}
{% endif %}
{% endfor %}
{% else %}
{% if other_language == config.default_language %}
{% set translation_url = config.base_url | safe %}
{% else %}
{% set translation_url = config.base_url ~ '/' ~ other_language %}
{% endif %}
{% set trimmed_path = current_path | trim_start_matches(pat='/') | trim_start_matches(pat=lang) %}
{% set translation_url = translation_url ~ trimmed_path %}
{{ trimmed_path }}
{% endif %}
<a href="{{ translation_url }}"
class="bg-gray-200 text-gray-800 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-400 dark:hover:text-white p-1 rounded-full">
{% if config.extra.languages[lang].symbol %}{{ config.extra.languages[lang].symbol }}{% else %}{{ lang }}{% endif %}
{{ trans(key="language_symbol", lang=lang) }}
</a>
</div>
{% endif %}
Expand All @@ -220,15 +206,9 @@
<div
class="nav-links flex flex-col space-y-4 items-center w-screen bg-gray-200 dark:bg-gray-800 transition-all ease-out duration-500 h-0">
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
{% for item in config.extra.navbar.items %}
{% if lang == item.lang %}
{% for link in item.links %}
<a href="{{ config.base_url | trim_end_matches(pat='/') | safe }}/{{ link.url }}"
class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">{{
link.name }}</a>
{% endfor %}
{% endif %}
{% endfor %}
{{ macros::navbar_button(url="", text=trans(key="home", lang=lang)) }}
{{ macros::navbar_button(url="projects", text=trans(key="projects", lang=lang)) }}
{{ macros::navbar_button(url="skills", text=trans(key="skills", lang=lang)) }}

{% if config.extra.sidebar.items %}
{% for item in config.extra.sidebar.items %}
Expand All @@ -254,7 +234,7 @@

<!----------------------------------------------------------->
<!------------------------- PAGINATION ---------------------->
<!----------------------------------------------------------->
<!------------------------- ---------------------------------->
{% block pagination %}
{% endblock%}

Expand Down
29 changes: 18 additions & 11 deletions templates/macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,26 @@
{% for term in terms %}
{# Show term only if its item count is between minimum and maximum amount (if those parameters are given) #}
{% if (not minimum_amount or term.pages | length >= minimum_amount) and (not maximum_amount or term.pages | length <= maximum_amount) %}
<a href="{{ term.permalink | safe }}" class="flex items-center space-x-2">
<a href="{{ term.permalink | safe }}" class="flex items-center space-x-2">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="{{ icon_definition }}">
</path>
</svg>
<span class="text-bold">{{term.name}} <sup>{{ term.pages | length }}</sup></span>
</a>
<span class="text-bold">{{ term.name }} <sup>{{ term.pages | length }}</sup></span>
</a>
{% endif %}
{% endfor %}
</div>
{% endmacro %}

<!-- Shows a list of all given terms of a taxonomy with the projects terms icon in front of each term. -->
{% macro terms_list_projects(terms) %}
{{ macros::terms_list(terms=terms, icon_definition="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0
012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2
0 012-2h6a2 2 0 012 2v2M7 7h10") }}
{{ macros::terms_list(terms=terms, icon_definition="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10") }}
{% endmacro %}

<!-- Shows a list of all given terms of a taxonomy with the skills terms icon in front of each term. -->
{% macro terms_list_skills(terms, maximum_amount='', minimum_amount='') %}
{{ macros::terms_list(terms=terms, maximum_amount=maximum_amount, minimum_amount=minimum_amount, icon_definition="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7
7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0
014-4z") }}
{{ macros::terms_list(terms=terms, maximum_amount=maximum_amount, minimum_amount=minimum_amount, icon_definition="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z") }}
{% endmacro %}


Expand Down Expand Up @@ -112,7 +108,7 @@ <h2 class="text-2xl text-bold pt-0"><a href='{{ page.permalink }}'>{{ page.title
<!-- Read more link -->
<div class="flex items-center w-1/3 mb-2">
<a class="flex" href='{{ page.permalink }}'>
Read More
{{ trans(key="read_more", lang=lang) }}
<svg class="w-6 h-6 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
Expand All @@ -124,11 +120,22 @@ <h2 class="text-2xl text-bold pt-0"><a href='{{ page.permalink }}'>{{ page.title

<!-- Skills & Technologies Section -->
{% if page.taxonomies.skills %}
<h2>Skills & Technologies</h2>
<h2>{{ trans(key="skills_technologies", lang=lang) }}</h2>
{{ macros::project_list_skills(skills=page.taxonomies.skills, lang=lang) }}
{% endif %}

</span>
</div>
</div>
{% endmacro %}

{% macro navbar_button(url, text) %}
{%if lang == config.default_language %}{% set language_url_part = '' %}{% else %}{% set language_url_part = lang %}{% endif %} {# Empty for default language and language for others. #}
<a href="{{ config.base_url | trim_end_matches(pat='/') | safe }}/{{ language_url_part }}/{{ url }}"
{% if current_path and ((url != "" and url in current_path) or (url == "" and current_path | trim_end_matches(pat=lang ~'/') | trim_end_matches(pat='/') == "")) %}
class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium" {# Highlight button, if button URL is part of the current path. #}
{% else %}
class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
{% endif %}
>{{ text }}</a>
{% endmacro %}
12 changes: 6 additions & 6 deletions templates/skills/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@

{% block content %}

{% set page = get_page(path="skills.md", lang=lang) %}
{%- set page = get_page(path="skills.md", lang=lang) -%}
<div class="flex items-center flex-col mt-10 px-4">
<h1 class="text-2xl text-bold">{{ page.title }}</h1>

<div class="text-bold mt-4">{{ page.content | safe }}</div>

{% if config.extra.skills.main_skills_threshold %}
{% if config.extra.skills.main_skills_heading[lang] %}<h2> {{ config.extra.skills.main_skills_heading[lang] }}</h2>{% endif %}
{{ macros::terms_list_skills_main(terms=terms, threshold=config.extra.skills.main_skills_threshold) }}
{%- if config.extra.main_skills_threshold -%}
<h2>{{ trans(key="main_skills", lang=lang) }}</h2>
{{ macros::terms_list_skills_main(terms=terms, threshold=config.extra.main_skills_threshold) }}

{% if config.extra.skills.other_skills_heading[lang] %}<h2>{{ config.extra.skills.other_skills_heading[lang] }}</h2>{% endif %}
{{ macros::terms_list_skills_other(terms=terms, threshold=config.extra.skills.main_skills_threshold) }}
<h2>{{ trans(key="other_skills", lang=lang) }}</h2>
{{ macros::terms_list_skills_other(terms=terms, threshold=config.extra.main_skills_threshold) }}
{% else %}
{{ macros::terms_list_skills(terms=terms) }}
{% endif %}
Expand Down
Loading

0 comments on commit 35d077a

Please sign in to comment.