Commit c37fe01d authored by Marien Fressinaud's avatar Marien Fressinaud

tec: Reorganize the file structure

parents 5d2ca30d 9eb9c2a8
...@@ -32,60 +32,66 @@ $ source ~/.bashrc ...@@ -32,60 +32,66 @@ $ source ~/.bashrc
## Usage ## Usage
First, create a project directory: First, create a project and execute the Boop! command:
```console ```console
$ mkdir my-website && cd my-website $ mkdir my-website && cd my-website
``` $ echo '<h1>Welcome!</h1>' > index.html
Create a `./content` folder and execute the Boop! command:
```console
$ mkdir content
$ echo '<h1>Welcome!</h1>' > content/index.html
$ boop.py $ boop.py
Boop! Boop!
``` ```
Now, you should have your "production-ready" website under a `./output` folder. Now, you should have your "production-ready" website under a `./site` folder
that you can upload on your server.
For example, if your website consists in a single `index.html` page, you should
obtain the following structure:
```console ```console
$ tree $ tree
. .
├── content ├── index.html
│   └── index.html └── site
└── output
└── index.html └── index.html
``` ```
Boop! basically just copied `content` files under a `output` directory. But it Well OK, Boop! basically just copied the `index.html` file under the `site`
can convert Markdown files in HTML too. For that, you'll need a template file directory. Let's write an article then.
for articles:
For that, you'll need a template file under a `./theme` folder:
```console ```console
$ mkdir theme $ mkdir theme
$ echo '<html><body>{{ ARTICLE_CONTENT }}</body></html' > theme/article.html $ echo '<html><body>{{ ARTICLE_CONTENT }}</body></html' > theme/article.html
``` ```
Then, you can create your Markdown file as you did with the HTML one: Then, you can create a Markdown file under a `./articles` folder:
```console ```console
$ echo '# Welcome!' > content/markdown-index.md $ mkdir articles
$ echo '# My first article' > articles/my-article.md
$ boop.py $ boop.py
$ echo output/markdown-index.html $ tree
<html><body><h1>Welcome!</h1></body></html> .
├── articles
│   └── my-article.md
├── site
│   ├── index.html
│   ├── my-article.html
├── theme
│   └── article.html
└── index.html
$ echo site/my-article.html
<html><body><h1>My first article</h1></body></html>
``` ```
Please note that `./articles` folder only accepts Markdown files (i.e.
extension is `.md`).
You can define meta variables in the Markdown file which will be accessible You can define meta variables in the Markdown file which will be accessible
then in the template. Variables are uppercased and prepended by `ARTICLE_`. For then in the template. Variables are uppercased and prepended by `ARTICLE_`. For
example, for the following Markdown file: example, for the following Markdown file:
```markdown ```markdown
--- ---
title: Welcome! title: An article
author: Marien author: Marien
--- ---
...@@ -113,10 +119,10 @@ It will produce the following file: ...@@ -113,10 +119,10 @@ It will produce the following file:
```html ```html
<html> <html>
<head> <head>
<title>Welcome!</title> <title>An article</title>
</head> </head>
<body> <body>
<h1>Welcome!</h1> <h1>An article</h1>
<p>By Marien</p> <p>By Marien</p>
<p>This is my article.</p> <p>This is my article.</p>
...@@ -128,6 +134,25 @@ For now, you can use any valid Python expression between `{{ }}`, you have ...@@ -128,6 +134,25 @@ For now, you can use any valid Python expression between `{{ }}`, you have
access to the variables defined in the meta header, the Python builtin access to the variables defined in the meta header, the Python builtin
functions and the `datetime` module. functions and the `datetime` module.
The `./theme` folder can contain a `static` folder as well. Its content will be
copied under the `./site` folder:
```console
$ tree
.
├── articles
│   └── my-article.md
├── site
│   ├── index.html
│   ├── my-article.html
│   └── style.css
├── theme
│   ├── static
│   │   └── style.css
│   └── article.html
└── index.html
```
## Tests ## Tests
There are some tests (i.e. doctests) that can be run to check that everything There are some tests (i.e. doctests) that can be run to check that everything
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import os import os
import sys import sys
import shutil import shutil
import distutils.dir_util
import locale import locale
import markdown import markdown
...@@ -40,13 +41,6 @@ def dir_tree(path): ...@@ -40,13 +41,6 @@ def dir_tree(path):
yield filename yield filename
def mkdirs_for_file(filepath):
"""Create parent directories for a given file.
"""
path = os.path.dirname(filepath)
os.makedirs(path, exist_ok=True)
def convert_meta_to_article_vars(meta): def convert_meta_to_article_vars(meta):
"""Convert Markdown Meta to vars for article layout. """Convert Markdown Meta to vars for article layout.
""" """
...@@ -62,53 +56,63 @@ def convert_meta_to_article_vars(meta): ...@@ -62,53 +56,63 @@ def convert_meta_to_article_vars(meta):
def main(): def main():
# Check that content directory exists on the filesystem # Make sure ./site folder is empty
content_path = os.path.join(os.curdir, "content") output_path = os.path.join(os.curdir, "site")
if not os.path.isdir(content_path):
raise ProgramError("./content directory does not exist")
# Make sure output dir doesn't exist
output_path = os.path.join(os.curdir, "output")
if os.path.isdir(output_path): if os.path.isdir(output_path):
# it should be a directory... # it should be a directory...
shutil.rmtree(output_path) shutil.rmtree(output_path)
elif os.path.exists(output_path): elif os.path.exists(output_path):
# ... but it also can be a simple file if user created it manually! # ... but it also can be a simple file if user created it manually!
os.remove(output_path) os.remove(output_path)
os.makedirs(output_path, exist_ok=True)
# Check that index file exists and copy it under the ./site folder
index_filepath = os.path.join(os.curdir, "index.html")
if not os.path.exists(index_filepath):
raise ProgramError("./index.html file does not exist")
index_output_filepath = os.path.join(output_path, "index.html")
shutil.copyfile(index_filepath, index_output_filepath)
# Check that a ./theme/static folder exists and copy its content under the
# ./site folder
static_dirpath = os.path.join(os.curdir, "theme", "static")
if os.path.isdir(static_dirpath):
distutils.dir_util.copy_tree(static_dirpath, output_path)
# Check that articles directory exists on the filesystem
articles_path = os.path.join(os.curdir, "articles")
if not os.path.isdir(articles_path):
# If not, just stop here
return
md = markdown.Markdown(extensions=["meta", "fenced_code", "attr_list"]) md = markdown.Markdown(extensions=["meta", "fenced_code", "attr_list"])
# And copy the files from ./content to ./output # And copy the files from ./articles to ./site
for filepath in dir_tree(content_path): for filename in dir_tree(articles_path):
base, ext = os.path.splitext(filepath) base, ext = os.path.splitext(filename)
content_filepath = os.path.join(content_path, filepath) if ext != ".md":
output_filepath = os.path.join(output_path, filepath) # Don't consider files which are not Markdown
if ext == ".md": next
output_filepath = os.path.join(output_path, f"{base}.html")
article_filepath = os.path.join(articles_path, filename)
# First we need to create all the parent directories for our file output_filepath = os.path.join(output_path, f"{base}.html")
mkdirs_for_file(output_filepath)
# We convert the file's content into HTML
if ext == ".md": with open(article_filepath, "r") as article_file:
# Then, if it is a Markdown file, we convert it html = md.convert(article_file.read())
with open(content_filepath, "r") as content_file:
html = md.convert(content_file.read()) # We initialize the template
article_template_filepath = os.path.join("theme", "article.html")
# We initialize the template template = boopsy.Template(article_template_filepath)
article_template_filepath = os.path.join("theme", "article.html")
template = boopsy.Template(article_template_filepath) # We get the local variables from the Markdown file (metadata)
# which will be accessible in the article template
# We get the local variables from the Markdown file (metadata) article_vars = convert_meta_to_article_vars(md.Meta)
# which will be accessible in the article template article_vars["ARTICLE_CONTENT"] = html
article_vars = convert_meta_to_article_vars(md.Meta)
article_vars["ARTICLE_CONTENT"] = html # And we write the content in the output file
with open(output_filepath, "w") as output_file:
# And we write the content in the output file output_file.write(template.render(article_vars))
with open(output_filepath, "w") as output_file:
output_file.write(template.render(article_vars))
else:
# ... else, we simply copy the file to the output directory
shutil.copyfile(content_filepath, output_filepath)
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment