Commits: 14
Let a developer publish from unclean source repo
It's helpful when developing or debugging the publish.nu script.
index 2d0e5be..039730a 100755
--- a/publish.nu
+++ b/publish.nu
@@ -2,6 +2,7 @@
=def main [
= --source: path = "." # path to the source repository
= --pages: path = "./pages.git" # path to the Codeberg Pages repository
+ --allow-unclean # do not stutter on unclean repo. Useful when hacking on this script.
=] {
= # A record of information about source and pages repositories gathered as we go.
= mut spec = {
@@ -9,7 +10,7 @@ def main [
= pages_path: ($pages | path expand)
= }
=
- if (not (git is-clean $spec.source_path)) {
+ if (not ((git is-clean $spec.source_path) or $allow_unclean)) {
= error make --unspanned {
= msg: $"The source repository is not clean.",
= help: $"First commit, then publish. Here are the changes:\n\n (git status --porcelain)"Fix publish script failing when public/ is removed
After running zola serve the public directory is removed. This is to
prevent stale files from lingering there. From git perspective, it leads
to non-existing worktree. The solution is to just re-create this
directory.
index 039730a..1fcf2c2 100755
--- a/publish.nu
+++ b/publish.nu
@@ -19,6 +19,9 @@ def main [
=
= $spec.branch = git current-branch $spec.source_path
=
+ # Make sure the worktree exists. Zola has a strange habit of deleting public/
+ git ensure worktree $spec.pages_path
+
= git clean-repo $spec.pages_path
= git switch-or-create $spec.pages_path $spec.branch
=
@@ -70,6 +73,12 @@ def "git current-branch" [repo: path]: nothing -> string {
= git symbolic-ref --short HEAD
=}
=
+def "git ensure worktree" [repo: path] {
+ cd $repo
+ let worktree_path = git config --get core.worktree
+ mkdir $worktree_path
+}
+
=def "git clean-repo" [repo: path] {
= cd $repo
= print $"Cleaning ($repo) worktree..."Fix publish script wrongly detecting remote tracking
The idiomatic Nushell way to suppress error message is to pipe to
ignore command. But it has a side effect of supressing the error
itself. So in a try - catch block, it swallows the error I want to
detect.
For now I opted to classic Unix way of redirecting to /dev/null. It will probably make the script not compatible with Windows. Oh noes!
index 1fcf2c2..ce53715 100755
--- a/publish.nu
+++ b/publish.nu
@@ -133,7 +133,7 @@ def "git has branch" [repo: path, branch: string] {
=# Check if the current branch is tracking a remote.
=def "git is-tracking" [] {
= try {
- git rev-parse --abbrev-ref --symbolic-full-name @{u} err>| ignore
+ git rev-parse --abbrev-ref --symbolic-full-name @{u} err> /dev/null
= true
= } catch {
= falseImplement a dry-run mode for publish.nu
It will show the commit message and diff, but won't actually commit.
index ce53715..e661123 100755
--- a/publish.nu
+++ b/publish.nu
@@ -3,6 +3,7 @@ def main [
= --source: path = "." # path to the source repository
= --pages: path = "./pages.git" # path to the Codeberg Pages repository
= --allow-unclean # do not stutter on unclean repo. Useful when hacking on this script.
+ --dry-run # do everything else, but don't commit or push
=] {
= # A record of information about source and pages repositories gathered as we go.
= mut spec = {
@@ -47,7 +48,17 @@ Changes since ($spec.last_deployment_time | date to-timezone utc | format date '
= $spec | table --expand | print
= input --numchar 1 "Press any key to continue, or ctrl-c to abort."
=
- $commit_template | git publish $spec.pages_path $spec.branch
+ if ($dry_run) {
+ print "---"
+ print $commit_template
+ print "---"
+ print "☝ this would be the commit message. You would have a chance to edit it."
+ input --numchar 1 "I will show you a diff now. Press any key when ready."
+ cd $spec.pages_path
+ git diff
+ } else {
+ $commit_template | git publish $spec.pages_path $spec.branch
+ }
=}
=
=# Takes commit message as inputHandle /@branch-preview/ prefix in links
The build script will pass the prefix as base_url to zola. All linked assets and hyperlinks should now use this prefix.
index e661123..cc7ecf9 100755
--- a/publish.nu
+++ b/publish.nu
@@ -42,7 +42,11 @@ Changes since ($spec.last_deployment_time | date to-timezone utc | format date '
=($spec.changelog | format changelog)
= "
=
- zola build
+ let base_url = match $spec.branch {
+ "main" => "/",
+ _ => $"/@($spec.branch)/"
+ }
+ zola build --base-url $base_url
=
= print "About to commit and publish. Here is the summary: "
= $spec | table --expand | printindex 12a7973..fa7c605 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -32,12 +32,12 @@
= <meta name="description" content="{\{ description \}}" />
= <meta name="viewport" content="width=device-width, initial-scale=1" />
=
- <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
- <link rel="shortcut icon" href="/favicon.ico" />
- <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
+ <link rel="icon" type="image/png" href="{\{ get_url(path='/favicon-96x96.png') \}}" sizes="96x96" />
+ <link rel="icon" type="image/svg+xml" href="{\{ get_url(path='/favicon.svg') \}}" />
+ <link rel="shortcut icon" href="{\{ get_url(path='/favicon.ico') \}}" />
+ <link rel="apple-touch-icon" sizes="180x180" href="{\{ get_url(path='/apple-touch-icon.png') \}}" />
= <meta name="apple-mobile-web-app-title" content="{\{ config.title \}}" />
- <link rel="manifest" href="/site.webmanifest" />
+ <link rel="manifest" href="{\{ get_url(path='/site.webmanifest') \}}" />
=
= <meta property="og:title" content="{\{ title \}}">
= <meta property="og:type" content="website" />Separate services to own section, with emojis 😎
index 435d9d3..a834d7f 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -10,60 +10,14 @@ Based entirely in Europe, [our team](@/people/_index.md) is on-shore, allowing u
=
=# Our Services
=
-Our primary focus is on helping European Small and Medium-sized Enterprises (SMEs), Non-Governmental Organizations (NGOs), local governments, and educational institutions with implementing free, open-source and European software solutions.
+Our primary focus is on helping European Small and Medium-sized Enterprises (SMEs), Non-Governmental Organizations (NGOs), local governments, and educational institutions with implementing free, open-source and European software solutions. We provide
=
+🌤️ Cloud assistance
=
-## Cloud assistance
+💻 Software Development
=
-Your organisation probably depends on multiple cloud services. Setting up, managing and migrating cloud services can be complicated. Or maybe your company is or wants to self-host some applications? Our team is happy to assist you on projects or provide operational support for your cloud and self-hosted services.
+💬 Consulting
=
-Our technical capabilities include:
+📖 Training and coaching
=
- * Cloud infrastructure: Kubernetes, Docker, OpenShift, and pretty much any Cloud provider
- * Infrastructure automation: Terraform, Ansible, GitOps with ArgoCD, GitHub Actions, Jenkins
- * Service architecture: service mesh, service discovery, containerization, server-less
- * System reliability: monitoring (Prometheus, Grafana, Nagios), observability, high availability
- * Linux, Unix wizardry
- * Scripting
-
-Reach out to us for any project or operational support in
-
- * Setting up cloud or self-hosted services, applications
- * Migrating your cloud or self-hosted services
- * Administering your cloud or self-hosted services
- * Trusted Admin Failover as a Service (TAFaaS), if you would like to have a backup plan when your trusted admin is absent unexpectedly
-
-
-## Software Development
-
-Need any customization or extension of FOSS functionalities? Need hard coding skills to set up a (web)application? Want to automate some tasks? Our team has a broad technical skillset, including (but not limited to):
-
- * HTML, CSS, JavaScript
- * Python
- * Rust
- * Elm
- * Haskell
- * Groovy
- * SQL
- * Bash
- * Go
-
-
-## Consulting
-
-We can assist with small and big projects, provide momentary advice or define long term strategies for your organisation. Some examples:
-
- * Project management
- * Define migration strategies from concept to technical detail, for example moving to a new collaborative software platform (email, calendar, file sharing, etc.)
- * Define technical solutions to meet your data security and data privacy requirements
-
-
-## Training and coaching
-
-We can provide training and coaching on different topics. The following list is not exhaustive, don't hesitate to reach out for other needs in the FOSS domain:
-
- * Web Development
- * Agile development, Test driven development, Pair prohramming
- * Relational Databases (RDBMS)
- * Version management using Git
- * Operating Systems (Linux, Nix / NixOS)
+[Read more about our services](@/services/_index.md)new file mode 100644
index 0000000..190f667
--- /dev/null
+++ b/content/services/_index.md
@@ -0,0 +1,63 @@
+---
+title: Services
+---
+
+# Our Services
+
+Our primary focus is on helping European Small and Medium-sized Enterprises (SMEs), Non-Governmental Organizations (NGOs), local governments, and educational institutions with implementing free, open-source and European software solutions.
+
+
+## 🌤 ️Cloud assistance
+
+Your organisation probably depends on multiple cloud services. Setting up, managing and migrating cloud services can be complicated. Or maybe your company is or wants to self-host some applications? Our team is happy to assist you on projects or provide operational support for your cloud and self-hosted services.
+
+Our technical capabilities include:
+
+ * Cloud infrastructure: Kubernetes, Docker, OpenShift, and pretty much any Cloud provider
+ * Infrastructure automation: Terraform, Ansible, GitOps with ArgoCD, GitHub Actions, Jenkins
+ * Service architecture: service mesh, service discovery, containerization, server-less
+ * System reliability: monitoring (Prometheus, Grafana, Nagios), observability, high availability
+ * Linux, Unix wizardry
+ * Scripting
+
+Reach out to us for any project or operational support in
+
+ * Setting up cloud or self-hosted services, applications
+ * Migrating your cloud or self-hosted services
+ * Administering your cloud or self-hosted services
+ * Trusted Admin Failover as a Service (TAFaaS), if you would like to have a backup plan when your trusted admin is absent unexpectedly
+
+
+## 💻 Software Development
+
+Need any customization or extension of FOSS functionalities? Need hard coding skills to set up a (web)application? Want to automate some tasks? Our team has a broad technical skillset, including (but not limited to):
+
+ * HTML, CSS, JavaScript
+ * Python
+ * Rust
+ * Elm
+ * Haskell
+ * Groovy
+ * SQL
+ * Bash
+ * Go
+
+
+## 💬 Consulting
+
+We can assist with small and big projects, provide momentary advice or define long term strategies for your organisation. Some examples:
+
+ * Project management
+ * Define migration strategies from concept to technical detail, for example moving to a new collaborative software platform (email, calendar, file sharing, etc.)
+ * Define technical solutions to meet your data security and data privacy requirements
+
+
+## 📖 Training and coaching
+
+We can provide training and coaching on different topics. The following list is not exhaustive, don't hesitate to reach out for other needs in the FOSS domain:
+
+ * Web Development
+ * Agile development, Test driven development, Pair prohramming
+ * Relational Databases (RDBMS)
+ * Version management using Git
+ * Operating Systems (Linux, Nix / NixOS)new file mode 100644
index 0000000..61d3aed
--- /dev/null
+++ b/templates/section.html
@@ -0,0 +1,7 @@
+{# A generic section template #}
+
+{\% extends "base.html" %}
+
+{\%- block main_content -%}
+{\{- section.content | safe -\}}
+{\%- endblock main_content -%}Fix publish script to handle comma in a commit message
index cc7ecf9..a2da6c8 100755
--- a/publish.nu
+++ b/publish.nu
@@ -159,8 +159,8 @@ def "git is-tracking" [] {
=
=def "git changelog" [repo: path, since: datetime]: nothing -> table {
= cd $repo
- git log --pretty=reference --date=iso-strict
- | parse "{hash} ({title}, {date})"
+ git log --pretty="format:%h\t%s\t%cd" --date=iso-strict
+ | parse "{hash}\t{title}\t{date}"
= | update date { |row| $row.date | into datetime }
= | where date > $since
=}Increase vertical space above the footer
It was unpleasantly narrow.
index fa7c605..3e9f69c 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -96,6 +96,7 @@
= }
=
= body > footer {
+ margin-top: 3rem;
= display: flex;
= background: var(--dark-color);
= align-items: center;
@@ -129,7 +130,6 @@
=
= #logo {
= height: 3em;
- width: 3em;
= }
=
= p {
@@ -177,7 +177,9 @@
= /* UTILITY CLASSES */
=
= .full-bleed-background {
- margin: 0 calc(-1 * var(--full-bleed-margin));
+ --negative-margin: calc(-1 * var(--full-bleed-margin));
+ margin-left: var(--negative-margin);
+ margin-right: var(--negative-margin);
= padding: 3rem calc(1rem + var(--full-bleed-margin));
= }
=Move the tera context element to the top
Below the footer it was creating an uncanny bright stripe.
index 3e9f69c..2115811 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -291,6 +291,13 @@
= </p>
= <![endif]-->
=
+ {\%- if config.mode == "serve" %}
+ <details style="overflow: scroll">
+ <summary>Rendering context</summary>
+ <pre>{\{ __tera_context | escape | safe \}}</pre>
+ </details>
+ {\% endif -%}
+
= <header>
= <a href="{\{ get_url(path='@/_index.md') \}}">
= <img
@@ -347,13 +354,5 @@
= </ul>
= </footer>
=
- {\% if config.mode == "serve" %}
- <details style="overflow: scroll">
- <summary>Rendering context</summary>
- <pre>
-{\{ __tera_context | escape | safe \}}
- </pre>
- </details>
- {\% endif %}
= </body>
=</html>Remove obsolete --prompt-font-size variable
It was used in a very confusing way to set the height of main logo. Must have been a relic of some early experiments with the funny prompt.
Now the logo is simply sized in rem units. Visually there should be no change.
index 2115811..27db92b 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -54,7 +54,6 @@
= --prompts-count: 19;
= --max-prompt-length: 63;
= --prompt-height: 1.5em;
- --prompt-font-size: 2rem;
= --container-width: 960px;
= --dark-color: hsl(0, 0%, 10%);
= --light-color: hsl(0, 0%, 90%);
@@ -76,7 +75,6 @@
= }
=
= body > header {
- font-size: var(--prompt-font-size);
= color: var(--dark-color);
= padding: 3rem 1rem;
= overflow: hidden;
@@ -129,7 +127,7 @@
= }
=
= #logo {
- height: 3em;
+ height: 6rem;
= }
=
= p {
@@ -268,7 +266,7 @@
=
= @media (max-width: 36rem) {
= #logo {
- height: 2em;
+ height: 4rem;
= }
=
= .title > h1 {Create an extremely simple main nav element
index 27db92b..5d017ce 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -101,6 +101,13 @@
= color: var(--light-color);
= }
=
+ nav > ul {
+ display: flex;
+ justify-content: end;
+ flex-wrap: wrap;
+ gap: 2rem;
+ }
+
= hgroup h1 {
= margin: 0;
= font-weight: 400;
@@ -297,6 +304,13 @@
= {\% endif -%}
=
= <header>
+ <nav>
+ <ul>
+ <li><a href="{\{get_url(path='@/_index.md')\}}">Home</a></li>
+ <li><a href="{\{get_url(path='@/people/_index.md')\}}">People</a></li>
+ <li><a href="{\{get_url(path='@/services/_index.md')\}}">Services</a></li>
+ </ul>
+ </nav>
= <a href="{\{ get_url(path='@/_index.md') \}}">
= <img
= id="logo"Make bullets in main nav look like LEDs
To add a bit of playfulness. Also make the labels stronger.
Under the hood, navigation element is now controlled by site configuration (extra section in config.toml file).
index badacc2..1de2490 100644
--- a/config.toml
+++ b/config.toml
@@ -20,3 +20,15 @@ highlight_code = true
=
=[extra]
=# Put all your custom variables here
+[[extra.navigation]]
+label = "Home"
+class = "green-accent"
+path = "_index.md"
+[[extra.navigation]]
+label = "People"
+class = "red-accent"
+path = "people/_index.md"
+[[extra.navigation]]
+label = "Services"
+class = "blue-accent"
+path = "services/_index.md"index 5d017ce..15e8068 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -55,14 +55,22 @@
= --max-prompt-length: 63;
= --prompt-height: 1.5em;
= --container-width: 960px;
- --dark-color: hsl(0, 0%, 10%);
- --light-color: hsl(0, 0%, 90%);
= --full-bleed-margin: max(
= 0px,
= calc(0.5 * (100vw - var(--container-width)))
= );
+
+
+ /* Colors */
+ --dark-color: hsl(0, 0%, 10%);
+ --light-color: hsl(0, 0%, 90%);
+
+ --red: oklch(36% 80% 29deg);
+ --green: oklch(from var(--red) L C 142deg);
+ --blue: oklch(from var(--red) L C 264deg);
= }
=
+
= body {
= font-family: sans-serif;
= padding: 0;
@@ -101,11 +109,52 @@
= color: var(--light-color);
= }
=
+
+ /* playful colors */
+ .red-accent {
+ --accent-color: var(--red)
+ }
+ .green-accent {
+ --accent-color: var(--green)
+ }
+ .blue-accent {
+ --accent-color: var(--blue)
+ }
+
= nav > ul {
= display: flex;
= justify-content: end;
= flex-wrap: wrap;
= gap: 2rem;
+ list-style: none;
+
+ li {
+ --inactive-color: oklch(from var(--accent-color) L 30% H);
+ --active-color: oklch(from var(--accent-color) 63% C H);
+
+ &::before {
+ content: "•";
+
+ color: var(--inactive-color);
+ transition: color 1s, text-shadow 1s;
+ }
+
+ &.active::before {
+ color: var(--active-color);
+ text-shadow: 0 0 4px var(--active-color), 0 0 4px var(--active-color);
+ }
+
+ &:hover::before {
+ color: var(--active-color);
+ text-shadow: 0 0 4px var(--active-color), 0 0 4px var(--active-color);
+ }
+
+ a {
+ font-weight: bold;
+ color: var(--dark-color);
+ }
+ }
+
= }
=
= hgroup h1 {
@@ -303,12 +352,28 @@
= </details>
= {\% endif -%}
=
+
= <header>
= <nav>
= <ul>
- <li><a href="{\{get_url(path='@/_index.md')\}}">Home</a></li>
- <li><a href="{\{get_url(path='@/people/_index.md')\}}">People</a></li>
- <li><a href="{\{get_url(path='@/services/_index.md')\}}">Services</a></li>
+ {# Code below assumes that every item points to a section.
+
+ If that's no longer the case, the code needs to get smarter.
+ Probably something to do with pattern matching on item.path.
+
+ 1. If it ends with _index.md it's a section,
+ 2. else if it it ends with .md it's a page,
+ 3. else if it starts with / it's a local asset (an image, pdf, etc.),
+ 4. else it's an external URL.
+ #}
+ {\%- for item in config.extra.navigation %}
+ {\%- set item_section = get_section(path=item.path) -%}
+ {\%- set is_active = item_section.path == current_path %}
+ <li class="{\{ item.class \}} {\% if is_active %}active{\% endif %}">
+ <a href="{\{ item_section.path \}}">{\{ item.label \}}</a>
+ </li>
+ {\% endfor -%}
+
= </ul>
= </nav>
= <a href="{\{ get_url(path='@/_index.md') \}}">Make the people accent yellow
Red might look like something is wrong.
I used a yellow color from our logo. Other accents are based on this color too, just with heu rotated in OKLCH space.
index 1de2490..fe8fec3 100644
--- a/config.toml
+++ b/config.toml
@@ -26,7 +26,7 @@ class = "green-accent"
=path = "_index.md"
=[[extra.navigation]]
=label = "People"
-class = "red-accent"
+class = "yellow-accent"
=path = "people/_index.md"
=[[extra.navigation]]
=label = "Services"index 15e8068..1901c72 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -65,9 +65,10 @@
= --dark-color: hsl(0, 0%, 10%);
= --light-color: hsl(0, 0%, 90%);
=
- --red: oklch(36% 80% 29deg);
- --green: oklch(from var(--red) L C 142deg);
- --blue: oklch(from var(--red) L C 264deg);
+ --yellow: oklch(0.8498 0.173865 86.5517); /* same as our logo */
+ --red: oklch(from var(--yellow) L C 29deg);
+ --green: oklch(from var(--yellow) L C 142deg);
+ --blue: oklch(from var(--yellow) L C 264deg);
= }
=
=
@@ -111,6 +112,9 @@
=
=
= /* playful colors */
+ .yellow-accent {
+ --accent-color: var(--yellow)
+ }
= .red-accent {
= --accent-color: var(--red)
= }
@@ -129,8 +133,8 @@
= list-style: none;
=
= li {
- --inactive-color: oklch(from var(--accent-color) L 30% H);
- --active-color: oklch(from var(--accent-color) 63% C H);
+ --inactive-color: oklch(from var(--accent-color) 60% C H);
+ --active-color: oklch(from var(--accent-color) 83% C H);
=
= &::before {
= content: "•";Add more space between nav bullets and labels
They were too close and it looked off.
index 1901c72..6987649 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -140,6 +140,7 @@
= content: "•";
=
= color: var(--inactive-color);
+ margin-right: 0.5ch;
= transition: color 1s, text-shadow 1s;
= }
=