Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 110 additions & 12 deletions .eleventy.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,67 @@
const moment = require('moment');
const crs = require('./crs/crs.js');
const { DateTime } = require('luxon');

moment.locale('en');

const pageAssetsPlugin = require('eleventy-plugin-page-assets');

module.exports = function (eleventyConfig) {
module.exports = async function (eleventyConfig) {

// https://www.11ty.dev/docs/languages/markdown/#indented-code-blocks
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.enable("code"));

// const pageAssetsPlugin = require('eleventy-plugin-page-assets');
let pageAssetsPlugin = await import('eleventy-plugin-page-assets');
pageAssetsPlugin = pageAssetsPlugin.default || pageAssetsPlugin;

// https://github.com/victornpb/eleventy-plugin-page-assets
eleventyConfig.addPlugin(pageAssetsPlugin, {
mode: "parse",
assetsMatching: "*.png|*.PNG|*.jpg|*.JPG|*.gif|*.GIF",
postsMatching: "**/*.md",
mode: "directory",
assetsMatching: "*.png|*.PNG|*.jpg|*.JPG|*.gif|*.GIF|*.cr|*.nr|*.txt",
postsMatching: "**/*.md",
hashAssets: false,
recursive: true,
silent: true,
});

// This replaces the {{ xyz | url }} filter by applying pathPrefix properly
// let { HtmlBasePlugin } = await import("@11ty/eleventy");
// HtmlBasePlugin = HtmlBasePlugin.default || HtmlBasePlugin;
// eleventyConfig.addPlugin(HtmlBasePlugin);

// This currently works best
// It replaces all links with links relative to the current file
eleventyConfig.addPlugin(relativeLinks);

eleventyConfig.addFilter('dateIso', date => {
return moment(date).toISOString();
if (!date) return '';
try {
const dt = date instanceof Date ? DateTime.fromJSDate(date) : DateTime.fromISO(String(date));
if (dt.isValid) return dt.toUTC().toISO();
// fallback to native parse
const d2 = new Date(String(date));
return isNaN(d2) ? '' : DateTime.fromJSDate(d2).toUTC().toISO();
} catch (e) { return ''; }
});

eleventyConfig.addFilter('dateReadable', date => {
return moment(date).utc().format('LL'); // E.g. May 31, 2019
// dateReadable: server-side formatted date using the provided locale (e.g. page.locale)
// Usage: {{ page.date | dateReadable(page.locale) }} — falls back to site locale or 'en'
eleventyConfig.addFilter('dateReadable', (date, locale) => {
if (!date) return '';
let dt = date instanceof Date ? DateTime.fromJSDate(date) : DateTime.fromISO(String(date));
if (!dt.isValid) dt = DateTime.fromJSDate(new Date(String(date)));

const site = require('./_data/site.json');
const useLocale = locale || site.locale || 'en';
return dt.setLocale(useLocale).toLocaleString(DateTime.DATE_FULL);
});

eleventyConfig.addShortcode('excerpt', article => extractExcerpt(article));

// Folders to copy to output folder
eleventyConfig.addPassthroughCopy("css");

crs(eleventyConfig);

// all reports go here
eleventyConfig.addPassthroughCopy("reports");

};

module.exports.config = {
Expand Down Expand Up @@ -64,3 +98,67 @@ function extractExcerpt(article) {

return excerpt;
}


/** Referring to HtmlBasePlugin.js
*
* This plugin tries to make all URLs in the HTML output relative to the page.
*
* Useful for:
* * browsing via file://
* * gh-pages in subdirectory repo
* * unsure where in the directory structure the site will be hosted
*
* We're expecting the internal links to start with "/"
*
* todo?
* * option to include "index.html" for those directory links, for extra file:// compat
*
*/

// import path from "path";
const path = require("path");

function relativeLinks(eleventyConfig) {
// Apply to all HTML output in your project
eleventyConfig.htmlTransformer.addUrlTransform(
"html",
function makeUrlRelative(urlInMarkup) {
// Skip empty URLs, non-root-relative URLs, and dev server image transform URLs
if (
!urlInMarkup
|| !urlInMarkup.startsWith("/")
|| urlInMarkup.startsWith("/.11ty/")
|| urlInMarkup.startsWith("//")
) {
if (urlInMarkup.endsWith("/") && urlInMarkup.startsWith("/")) {
return urlInMarkup + 'index.html';
}
if (urlInMarkup === "..") return "../index.html";
return urlInMarkup;
}

// Get base directory path (keep trailing slash for index pages)
const fromDir = this.url.endsWith("/") ? this.url : path.dirname(this.url);

let relativePath = path.relative(fromDir, urlInMarkup);

// Add ./ for same-directory references
if (!relativePath.startsWith(".")) {
relativePath = "./" + relativePath;
}

// Preserve trailing slash from original URL
if (urlInMarkup.endsWith("/") && !relativePath.endsWith("/")) {
relativePath += "/";
}
if (relativePath.endsWith("/"))
return relativePath + "index.html";

return relativePath;
},
{
priority: -1, // run last last (after PathToUrl)
},
);
}
3 changes: 3 additions & 0 deletions .eleventyignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# We don't want Eleventy to include the README.md as a website content file
README.md

# template directory: help for authors
# template/

# Unit tests should be ignored by Eleventy
tests/
132 changes: 125 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,139 @@
# eleventy-blog
An example blog site using Eleventy that covers fundamental functionality.
# Eressea Tutorial 2024

The following article accompanies this repo.
These are the diaries for the 2024 Eressea Tutorial.

## Creating A Blog With Eleventy
## How to add your diary

### Create your own fork of the repository

- Create a github account.

- Fork this repository by clicking on the [Fork Link in Github](https://github.com/eressea/tutorials/fork). This will create your private copy of the whole thing.

### Editing your content

- You can edit it directly on github or *clone* it to your computer and edit it there. Cloning requires more steps, but is ultimately more flexible. It requires you to learn a bit about version control with [git](https://git-scm.com/docs/gittutorial) and [github](https://docs.github.com/en/get-started/start-your-journey/hello-world)

- Create a subdirectory for your faction, for example 'dragonborns' (replace dragonborns below with the name of your directory).

- Copy the file called 'index.njk' from the 'template' directory into your subdirectory:

```
---
layout: overview-layout.njk
title: Not Goblins!
override:tags: ["race"]
pagination:
data: collections.nogoblin
size: 8
reverse: false
alias: posts
---
...
```

Change the title as you wish and 'nogoblin' to 'dragonborns'.

- If you want to create just one big file, replace everything below the second '---' with your content. This is not recommended if you want to add a lot of text. The content is [Markdown](https://www.markdownguide.org/), a text file format that let's you add basic formatting like headings, links, images. You could also use html directly. Then you would create an index.html file instead. HTML is less recommended.

- If you have more to say, you should split your diary into multiple files. In that case, just add a short intro below the '---'. Also copy 'Auswertung_XX.md' from the template directory into your subdirectory. You may rename them as you wish, for example to week_01.md, week_02.md, ... and so forth.

- Also copy the file template.json to your directory and rename it to dragonborns.json.
```
{
"author": "enno",
"layout": "post-layout.njk",
"tags": "nogoblin",
"locale": "de"
}
```
- Change the author to your name and "nogoblin" to "dragonborns".

- Change the locale to en if you want to write in English.

- Edit every Auswertung_XX.md:
```
---
title: "Dragonborn: Round 1"
date: 2024-03-17
---
## Was passiert ist
...
## Unser Plan
...
```

This file consists of the 'front matter' between the lines starting with '---'. It contains some meta data that will be used for presenting your files nicely.

- Change the title
- Change the date line. The files will be ordered by the 'date' field, so make sure to get that right.
- Write your text below the second '---' line

- If you're editing directly in github, 'commit' your changes using the github interface. You can commit directly to your 'main' branch.

### Including links to files

If you use images, .cr, .nr, or .txt files in your text they should be automatically handled.

If this does not work, it may help to instead create a subdirectory `/reports/dragonborns` (at the project root, not inside your dragonborns directory) and copy them there. Now they get copied to the site and you can link to them as `[my first report](/reports/dragonborns/1-drag.cr)`.

### Including cr maps

With the 'shortcode' crmap, readnr, showorders etc. you can include a cr directly into your file like so:

{% crmap './reports/dragonborns/123-drag.cr' %}

{% orderfile '/reports/template/befehle-42.txt' %}

{% readnr '/reports/template/334-42.nr' %}
{% shownr 'intro' %}

See template/Auswertung_01.md for more details and examples.

### Seeing your content

- If you have cloned your repository and are using a Linux system, you can run
```
npm install
npm run serve
```
in a terminal. Watch the terminal for error messages. If all went well, you can then see the generated pages at [http://localhost:8080/](http://localhost:8080/) (your port may vary).


### Uploading your content

- If you have cloned the repository to your computer, you must ['add'](https://git-scm.com/docs/gittutorial) and ['commit'](https://git-scm.com/docs/gittutorial) your changes, then 'push' them to your repository.

- Optional: Activate github actions and github-pages. TODO

- If you have pushed your changes or commited them on github and you are happy with them, create a ['pull request'](https://github.blog/developer-skills/github/beginners-guide-to-github-creating-a-pull-request/) for the actual eressea repository (sometimes called the 'upstream repository'). If you have changes, you should see a line like "This branch is 1 commit ahead of eressea/tutorials:main' on github. Use the 'contribute' button to 'Open a pull request'. Write a short comment explaining your changes and 'Create pull request'. This will notifiy the owners of the upstream repo to review your changes. If they like them, they will 'merge' them and they can be watched online. They may also have comments or questions or ask you for changes before actually merging them.



### Done!

You can see the current state of the tutorial on https://eressea.github.io/tutorials/.


## eleventy-blog

We use [11ty](https://www.11ty.dev/) for creating the documentation.

See here for an example using eleventy:

### Creating A Blog With Eleventy
[https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/](https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/)

A demo of the blog is hosted on Netlify:
[https://dazzling-almeida-ca0492.netlify.com/](https://dazzling-almeida-ca0492.netlify.com/)

## Branches
### Branches
This repo contains several branches that allow you to checkout the code at various stages of development.

## How do I run the site?
### How do I run the site?
```
npm install
npm run serve
```

Then access the site with the URL [http://localhost:8080/](http://localhost:8080/) (your port may vary).
Then access the site with the URL [http://localhost:8080/](http://localhost:8080/) (your port may vary).
3 changes: 3 additions & 0 deletions _data/site.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"locale": "de"
}
46 changes: 42 additions & 4 deletions _includes/base-layout.njk
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,56 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Eressea Beispielpartie</title>
<title>Eressea Beispielpartie - {{title}}</title>

<link rel="stylesheet" href="{{ '/css/site.css' }}">
{% if content.indexOf('crs-requires-css') !== -1 %}
<link rel="stylesheet" href="{{ '/css/crs.css' }}">
{% endif %}
{% if content.indexOf('crs-requires-js') !== -1 %}
Comment on lines +9 to +12
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using indexOf to check for CSS/JS requirements in content is fragile and could lead to false positives if the string appears in other contexts. Consider using a more robust method like checking for specific HTML attributes or using a dedicated flag in the front matter.

Suggested change
{% if content.indexOf('crs-requires-css') !== -1 %}
<link rel="stylesheet" href="{{ '/css/crs.css' }}">
{% endif %}
{% if content.indexOf('crs-requires-js') !== -1 %}
{% if crs_requires_css %}
<link rel="stylesheet" href="{{ '/css/crs.css' }}">
{% endif %}
{% if crs_requires_js %}

Copilot uses AI. Check for mistakes.
<script src="{{ '/crs/crs-passthrough.js' }}" defer></script>
{% endif %}

<link rel="stylesheet" href="{{ '/css/site.css' | url }}">
<!-- link href="https://fonts.googleapis.com/css?family=Roboto+Slab:700|Roboto&display=fallback" rel="stylesheet" -->
</head>
<body>
<header>
<a href="{{ '/' | url }}" class="link--home">Beispielpartie</a>
<a href="{{ '..' | url }}" class="link--up">Up</a>
<a href="{{ '/' }}" class="link--home">Beispielpartie</a>
<a href="{{ '..' }}" class="link--up">Up</a>
</header>
<main>
{{ content | safe }}
{%- set currentindex = 0 %}
{%- set lastindex = 0 %}
{%- set radius = 1 %}
{%- for pageEntry in pagination.pages %}
{%- if page.url == pagination.hrefs[ loop.index0 ] %}
{%- set currentindex = loop.index0 %}
{%- endif %}
{%- set lastindex = loop.index0 %}
{%- endfor %}

{%- if lastindex > 0 %}

<nav aria-labelledby="faction-pagination">
<ol class='navlist'>
{% if page.url != pagination.href.first and currentindex > 3 %}<li><a href="{{ pagination.href.first }}">1</a></li>{% endif %}
{% if pagination.href.previous %}<li><a href="{{ pagination.href.previous }}">&larr;</a></li>{% endif %}

{%- for pageEntry in pagination.pages %}
{% if page.url == pagination.hrefs[ loop.index0 ] %}
<li>{{ loop.index }}</li>
{% elif currentindex - loop.index0 <= radius and loop.index0 - currentindex <= radius %}
<li><a href="{{ pagination.hrefs[ loop.index0 ] }}">{{ loop.index }}</a></li>
{% elif currentindex - loop.index0 <= radius + 1 and loop.index0 - currentindex <= radius + 1 %}
<li>&hellip;</li>
{% endif %}
{%- endfor %}
{% if pagination.href.next %}<li><a href="{{ pagination.href.next }}">&rarr;</a></li>{% endif %}
{% if page.url != pagination.href.last and currentindex < lastindex - 1 %}<li><a href="{{ pagination.href.last }}">{{lastindex + 1}}</a></li>{% endif %}
</ol>
</nav>
{% endif %}
</main>
<footer>&copy; Eressea PBEM</footer>
</body>
Expand Down
21 changes: 21 additions & 0 deletions _includes/overview-layout.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
layout: base-layout.njk
---
{{ content | safe }}

{% for post in posts %}
<section>

<h2>
<a href="{{ post.url }}">{{ post.data.title }}</a>
</h2>

<time datetime="{{ post.date | dateIso }}">{{ post.date | dateReadable(locale) }}</time>

{% excerpt post %}

<a href="{{ post.url }}">Read more</a>

</section>
{% endfor %}

Loading
Loading