Install markdown-pages with the installation command first.
In a new folder, add a bit of Markdown to index.md and run markdown-pages.
http://localhost:8000 will show the docs/index.html that
results from converting index.md. The docs folder contains all the generated
pages and assets of the site, it is the public directory. Any changes made to
the sources will be reflected in docs automatically. Press CTRL+C to stop
the site generator and the web server.
mkdir my-website
cd my-website
echo "# Home" > index.md
markdown-pagesTo create a new page add a Markdown or HTML file. Markdown files are converted
to HTML with the help of a template. HTML files are copied to the docs folder
directly. Files with extensions .draft.md or .draft.html will be excluded,
and so will the files in each line of .exclude. Add content to about.md for
http://localhost:8000/about.html to appear.
echo "# About" > about.md
markdown-pagesPages themselves can set their metadata in the header. Add the required title,
description and author information to about.md to change the values shown at
http://localhost:8000/about.html.
---
title: My website
description: My website in cyberspace
author:
- Jane Dev
---
# AboutThe metadata folder contains YAML files that set page metadata, but page
headers will override them.
mkdir metadataCopy the header of about.md inside metadata/about.yaml, and add page links
to nav. Since the YAML file contains the same values, the page header can be
removed.
---
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
---The metadata/default.yaml file is applied to all pages, but a metadata file
for a page will override it. Move the contents of metadata/about.yaml to
metadata/default.yaml, and http://localhost:8000 will show
the new values.
mv metadata/about.yaml metadata/default.yamlThe sitemap at https://localhost:8000/sitemap.xml is
generated from metadata/sitemap.yaml. The required parameters are base and
url.loc. url.loc is relative to base.
---
base: https://www.my-website.net/
url:
- loc: index.html
lastmod: 2024-01-01
changefreq: monthly
priority: 0.5
---Add a link to the sitemap in the navigation list of metadata/default.yaml.
---
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: Sitemap
href: sitemap.xml
---The RSS feed at https://localhost:8000/rss.xml is generated
from metadata/rss.yaml. channel, channel.link, channel.title,
channel.description, item.link, item.title and item.description are
required. item.link, image.url and enclosure.url are relative to
channel.link. item.enclosure.length is in bytes.
Put a value like '{{index.html}}' in item.description to import the contents
of that file, or use a normal string for a description in plain text.
---
channel:
title: My website
link: https://www.my-website.net/
description: My website in cyberspace
item:
- link: index.html
title: Home
description: '{{index.html}}'
---Set the rss parameter and add a link to the RSS feed in the navigation list of
metadata/default.yaml.
---
rss: rss.xml
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
---The assets folder can contain anything, it is copied entirely to docs. To
copy any other file add it to a new line in .include.
mkdir assets
echo "There are more than 1 billion websites in cyberspace." > assets/fact.txt
echo "This project is open source." > LICENSE
echo LICENSE >> .includeIn page documents like index.md files are accessed via the assets route,
available at http://localhost:8000/assets.
# Home
- Download a [fact about the web](assets/fact.txt) in text format.
- Read the [LICENSE](LICENSE).Add a stylesheet to the assets folder, like assets/style.css.
main h1 {
font-size: 3em;
}Then add it to the metadata in metadata/default.yaml. style can include any
URL that responds with a valid stylesheet.
---
rss: rss.xml
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
style:
- assets/style.css
---Add a script to the assets folder, like assets/script.js.
alert("Hello, visitor!");Then add it to the metadata in metadata/default.yaml. script can include any
URL that responds with a valid script.
---
rss: rss.xml
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
style:
- assets/style.css
script:
- assets/script.js
---Add a module to the assets folder, like assets/Counter.js.
import htm from "https://esm.sh/htm";
import { h, render } from "https://esm.sh/preact";
import { useState } from "https://esm.sh/preact/hooks";
const html = htm.bind(h);
export function Counter() {
const [value, setValue] = useState(0);
return html`<button onClick=${() => setValue(value + 1)}>
Clicked ${value} ${value === 1 ? 'time' : 'times'}
</button>`;
}
render(html`<${Counter} />`, document.getElementById("counter"));Then add it to the metadata in metadata/default.yaml. module can include any
URL that responds with a valid module.
---
rss: rss.xml
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
style:
- assets/style.css
script:
- assets/script.js
module:
- assets/Counter.js
---To use the new module add an HTML element with id="counter" to a document like
index.md.
# Home
- Download a [fact about the web](assets/fact.txt) in text format.
- Read the [LICENSE](LICENSE).
<p id="counter"></p>The template folder contains HTML and XML files that use metadata to generate
page layouts.
mkdir templateTemplates are applied to pages by name. The template/index.html template is
applied to index.md. template/default.html is applied to all pages, but a
template for a page will override it.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
$if(base)$
<base href="$base$$file$">
$endif$
<title>$title$</title>
$if(author)$$
for(author)$
<meta name="author" content="$author$">
$endfor$
$endif$
$if(description)$
<meta name="description" content="$description$">
$endif$
$if(rss)$
<link rel="alternate" type="application/rss+xml" href="$rss$">
$endif$
$if(theme.style)$
$for(theme.style)$
<link rel="stylesheet" href="$theme.style$">
$endfor$
$endif$
$if(style)$
$for(style)$
<link rel="stylesheet" href="$style$">
$endfor$
$endif$
$if(theme.module)$
$for(theme.module)$
<script type="module" src="$theme.module$"></script>
$endfor$
$endif$
$if(module)$
$for(module)$
<script type="module" src="$module$"></script>
$endfor$
$endif$
</head>
<body>
<header>
<h1><a href="index.html">$title$</a>$if(description)$<br><small>$description$</small>$endif$</h1>
$if(nav)$
<nav>$for(nav)$<a href="$nav.href$">$nav.label$</a>$sep$ / $endfor$</nav>
$endif$
</header>
<main>
$body$
$if(counter)$<p id="counter"></p>$endif$
</main>
<footer>
<p><a href="index.html">$title$</a>$if(description)$<br><small>$description$</small>$endif$</p>
$if(nav)$
<nav>$for(nav)$<a href="$nav.href$">$nav.label$</a>$sep$ / $endfor$</nav>
$endif$
</footer>
$if(theme.script)$
$for(theme.script)$
<script src="$theme.script$"></script>
$endfor$
$endif$
$if(script)$
$for(script)$
<script src="$script$"></script>
$endfor$
$endif$
</body>
</html>Add the counter parameter to the metadata in metadata/default.yaml to show
the counter of the template.
---
rss: rss.xml
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
style:
- assets/style.css
script:
- assets/script.js
module:
- assets/Counter.js
counter: yes
---And remove the counter element from index.md.
# Home
- Download a [fact about the web](assets/fact.txt) in text format.
- Read the [LICENSE](LICENSE).The theme folder contains assets, metadata and templates used when the project
does not provide them. In that case, it will get them from the installation.
mkdir -p theme/assets theme/metadata theme/templateThe theme/assets folder can contain anything, it is copied entirely to docs.
In page documents like index.md files are accessed via the /theme route,
available at http://localhost:8000/theme. Use only the stylesheet and module.
mv assets/style.css assets/Counter.js theme/assetsUse the template from template/default.html and delete the empty folder.
mv template/default.html theme/template
rm -rf templatePut the metadata needed for a new project inside theme/metadata/default.yaml.
---
title: My website
description: My website in cyberspace
author:
- Jane Dev
nav:
- label: Home
href: index.html
theme:
style:
- theme/style.css
module:
- theme/Counter.js
counter: yes
---And leave only the metadata for the current project in metadata/default.yaml.
---
rss: rss.xml
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
script:
- assets/script.js
---The test folder contains Spock test cases named *Spec.groovy.
mkdir testTo check that the homepage, sitemap and feed exist add a new test for it, like
test/MySiteSpec.groovy.
/* groovylint-disable CompileStatic, JavaIoPackageAccess, NoWildcardImports */
/* groovylint-disable MethodName, FactoryMethodName, MethodReturnTypeRequired */
/* groovylint-disable ClassJavadoc, JUnitPublicNonTestMethod */
import spock.lang.*
class WebPagesSpec extends Specification {
def 'at least the index source should exist'() {
expect:
new File('index.md').exists()
}
def 'at least the index output should exist'() {
expect:
new File('docs/index.html').exists()
}
def 'the sitemap source should exist'() {
expect:
new File('metadata/sitemap.yaml').exists()
}
def 'the sitemap output should exist'() {
expect:
new File('docs/sitemap.xml').exists()
}
def 'the feed source should exist'() {
expect:
new File('metadata/rss.yaml').exists()
}
def 'the feed output should exist'() {
expect:
new File('docs/rss.xml').exists()
}
}Go live for free at Neocities, GitLab Pages, or
GitHub Pages. For self-hosting use the docs folder as the
public directory of the HTTP server.
The base URL can be set in metadata files like metadata/default.yaml with
base. Remember to update metadata/rss.yaml and metadata/sitemap.yaml
accordingly.
---
base: https://janedev.github.io/my-website/
rss: rss.xml
nav:
- label: Home
href: index.html
- label: About
href: about.html
- label: RSS
href: rss.xml
- label: Sitemap
href: sitemap.xml
script:
- assets/script.js
---The .rewrite file can be used to change the name of the generated HTML. Each
line should contain a key-value pair separated by :. A good example is using
the README document as the index page.
README:index
The Elements page lists everything the Markdown documents can show.