diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..a2ebe3a99
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,6 @@
+FROM alpine:3.16
+
+RUN apk --no-cache add python3 py3-pip asciidoctor git build-base py3-psutil python3-dev libffi-dev
+RUN pip install "Nikola[extras]" python-Levenshtein==0.12.1 pathlib beautifulsoup4 markdown && rm -rf /root/.cache/
+
+WORKDIR /nikola
diff --git a/README.md b/README.md
index 188f49926..797d5943b 100644
--- a/README.md
+++ b/README.md
@@ -19,26 +19,23 @@ The `tutorials` folder is structured with a first level of folders that represen
 
 The `documentation` folder contains the OF API reference and are also in markdown format. This docs are generated from the code but the `description` field in every class, function or var can be edited directly in the markdown files.
 
-## Setting up the site to build locally
-
-This site is built using [nikola](https://getnikola.com). There's some scripts in the root folder to make it easier to install and use.
+## Setting up the site to build locally using Docker
 
-1. First, if installing on Mac OS-X, make sure the Xcode command lines tools have been installed:
+This site is built using [nikola](https://getnikola.com).
+There's some scripts in the `bin/` folder that use Docker
+to make it easier to install and use.
+(Tested on MacOS).
 
-  ```bash
-  xcode-select --install
-  ```
-  and then install the following packages (If you do not have brew installed you can grab it from [brew.sh](http://brew.sh/)):
+* Pre-reqs: a working [Docker](https://www.docker.com/get-started/)
+  environment and *nix shell
+* Build an image (alpine linux, python3, nikola) with
+  `./bin/build_docker.sh` (delete the image with `./bin/rm_docker.sh`)
+* Build the site and serve it on `http://localhost:8000/` with `./nikola_auto_build.sh`
+* (Build the site only with `./nikola_build.sh`)
+* (Serve the site on `http://localhost:8000/` with `./nikola_serve.sh`)
 
-  ```bash
-  brew install python3
-  sudo easy_install pip
-  brew linkapps python3
-  ```
-
-2. From the ofSite source directory, run ./install.sh which installs nikola and all the needed dependencies. (This has only been tested on linux and OS-X). 
+## Setting up the site to build locally
 
-3. Please make sure the symbol link `~/nikola/.Python` to python3 path is correct before you run `install.sh` script.
 
 4. Finally add the following to your .basrc, .bash_profile or .zshrc file:
   `export XML_CATALOG_FILES="/usr/local/etc/xml/catalog"`
diff --git a/auto_build.sh b/auto_build.sh
deleted file mode 100755
index cf91e6317..000000000
--- a/auto_build.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-source nikola/bin/activate
-nikola doit_auto
-
diff --git a/bin/build_docker.sh b/bin/build_docker.sh
new file mode 100755
index 000000000..a5ad03131
--- /dev/null
+++ b/bin/build_docker.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker build \
+  -t "${DOCKER_IMAGE_TAG}" \
+  "${SCRIPT_DIR}/.."
diff --git a/bin/nikola_auto_build.sh b/bin/nikola_auto_build.sh
new file mode 100755
index 000000000..4042b0c45
--- /dev/null
+++ b/bin/nikola_auto_build.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker run \
+  --rm \
+  -ti \
+  -p 127.0.0.1:8000:8000/tcp \
+  -v "${SCRIPT_DIR}/..:/nikola" \
+  "${DOCKER_IMAGE_TAG}" \
+  nikola auto -a 0.0.0.0
diff --git a/bin/nikola_build.sh b/bin/nikola_build.sh
new file mode 100755
index 000000000..13f1feea0
--- /dev/null
+++ b/bin/nikola_build.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker run \
+  --rm \
+  -ti \
+  -p 127.0.0.1:8000:8000/tcp \
+  -v "${SCRIPT_DIR}/..:/nikola" \
+  "${DOCKER_IMAGE_TAG}" \
+  nikola build
diff --git a/bin/nikola_serve.sh b/bin/nikola_serve.sh
new file mode 100755
index 000000000..65854dee5
--- /dev/null
+++ b/bin/nikola_serve.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker run \
+  --rm \
+  -ti \
+  -p 127.0.0.1:8000:8000/tcp \
+  -v "${SCRIPT_DIR}/..:/nikola" \
+  "${DOCKER_IMAGE_TAG}" \
+  nikola serve -a 0.0.0.0
diff --git a/bin/rm_docker.sh b/bin/rm_docker.sh
new file mode 100755
index 000000000..0bd5e9484
--- /dev/null
+++ b/bin/rm_docker.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker image rm \
+  "${DOCKER_IMAGE_TAG}"
diff --git a/bin/sh_docker.sh b/bin/sh_docker.sh
new file mode 100755
index 000000000..0e3a2007a
--- /dev/null
+++ b/bin/sh_docker.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+DOCKER_IMAGE_TAG="ofsite/nikola:1.0"
+
+docker run \
+  --rm \
+  -ti \
+  -p 127.0.0.1:8000:8000/tcp \
+  -v "${SCRIPT_DIR}/..:/nikola" \
+  "${DOCKER_IMAGE_TAG}" \
+  /bin/ash
diff --git a/build.sh b/build.sh
deleted file mode 100755
index f47c4fad0..000000000
--- a/build.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-. nikola/bin/activate
-nikola build
-deactivate
-
diff --git a/conf.py b/conf.py
index 61a9308af..f1bef83ea 100644
--- a/conf.py
+++ b/conf.py
@@ -1169,7 +1169,7 @@
 
 # If you hate "Filenames with Capital Letters and Spaces.md", you should
 # set this to true.
-UNSLUGIFY_TITLES = True
+FILE_METADATA_UNSLUGIFY_TITLES = True
 
 # Additional metadata that is added to a post when creating a new_post
 # ADDITIONAL_METADATA = {}
diff --git a/plugins/asciidoc/README.md b/plugins/asciidoc/README.md
index 556f12f57..4840ace43 100644
--- a/plugins/asciidoc/README.md
+++ b/plugins/asciidoc/README.md
@@ -1,10 +1,9 @@
-Compiler plugin to support the AsciiDoc markup.
+Compiler plugin to support the AsciiDoc markup via the original `asciidoc` tool or via `asciidoctor`.
 
 Example usage of Nikola's *path handlers* in Asciidoc:
 
     link:link://slug/demo-page[Click here to go to the demo page]
 
-[More information about AsciiDoc](http://www.methods.co.nz/asciidoc/)
-
-
+[More information about AsciiDoc](https://asciidoc.org/)
 
+[More information about Asciidoctor](https://asciidoctor.org/)
diff --git a/plugins/asciidoc/asciidoc.plugin b/plugins/asciidoc/asciidoc.plugin
index dfc4c9f18..f0ae6ebfa 100644
--- a/plugins/asciidoc/asciidoc.plugin
+++ b/plugins/asciidoc/asciidoc.plugin
@@ -2,8 +2,11 @@
 Name = asciidoc
 Module = asciidoc
 
+[Nikola]
+PluginCategory = PageCompiler
+
 [Documentation]
 Author = Roberto Alsina
-Version = 0.3
+Version = 0.6
 Website = http://plugins.getnikola.com/#asciidoc
 Description = Compile ASCIIDoc into HTML
diff --git a/plugins/asciidoc/asciidoc.py b/plugins/asciidoc/asciidoc.py
index 1db5be1b6..b7be3ef6f 100644
--- a/plugins/asciidoc/asciidoc.py
+++ b/plugins/asciidoc/asciidoc.py
@@ -1,4 +1,4 @@
-## -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
 
 # Copyright © 2012-2014 Roberto Alsina and others.
 
@@ -30,12 +30,13 @@
 
 """
 
-import codecs
+import io
 import os
+import shlex
 import subprocess
 
 from nikola.plugin_categories import PageCompiler
-from nikola.utils import makedirs, req_missing, write_metadata
+from nikola.utils import makedirs, write_metadata
 
 try:
     from collections import OrderedDict
@@ -49,28 +50,55 @@ class CompileAsciiDoc(PageCompiler):
     name = "asciidoc"
     demote_headers = True
 
-    def compile_html(self, source, dest, is_two_file=True):
-        makedirs(os.path.dirname(dest))
+    def compile_string(self, data, source_path=None, is_two_file=True, post=None, lang=None):
+        """Compile asciidoc into HTML strings."""
         binary = self.site.config.get('ASCIIDOC_BINARY', 'asciidoc')
-        try:
-            subprocess.check_call((binary, '-b', 'html5', '-s', '-o', dest, source))
-        except OSError as e:
-            if e.strreror == 'No such file or directory':
-                req_missing(['asciidoc'], 'build this site (compile with asciidoc)', python=False)
+        options = self.site.config.get('ASCIIDOC_OPTIONS', '')
+        options = shlex.split(options)
+        command = [binary, '-b', 'html5', '-s'] + options + ['-']
+        if not is_two_file:
+            m_data, data = self.split_metadata(data, post, lang)
+
+        from nikola import shortcodes as sc
+        new_data, shortcodes = sc.extract_shortcodes(data)
+        p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        output = p.communicate(input=new_data.encode('utf8'))[0].decode('utf8')
+        output, shortcode_deps = self.site.apply_shortcodes_uuid(output, shortcodes, filename=source_path, extra_context={'post': post})
+        return output, p.returncode, [], shortcode_deps
+
+    def compile(self, source, dest, is_two_file=True, post=None, lang=None):
+        """Compile the source file into HTML and save as dest."""
+        makedirs(os.path.dirname(dest))
+        with io.open(dest, "w+", encoding="utf8") as out_file:
+            with io.open(source, "r", encoding="utf8") as in_file:
+                data = in_file.read()
+                output, error_level, deps, shortcode_deps = self.compile_string(data, source, is_two_file, post, lang)
+                out_file.write(output)
+            if post is None:
+                if deps.list:
+                    self.logger.error(
+                        "Cannot save dependencies for post {0} (post unknown)",
+                        source)
+            else:
+                post._depfile[dest] += shortcode_deps
+        if error_level == 0:
+            return True
+        else:
+            return False
 
     def create_post(self, path, **kw):
-        content = kw.pop('content', 'Write your post here.')
-        one_file = kw.pop('onefile', False)  # NOQA
-        is_page = kw.pop('is_page', False)  # NOQA
-        metadata = OrderedDict()
+        """Create a new post."""
+        content = kw.pop('content', None)
+        onefile = kw.pop('onefile', False)
+        # is_page is not used by create_post as of now.
+        kw.pop('is_page', False)
+        metadata = {}
         metadata.update(self.default_metadata)
         metadata.update(kw)
         makedirs(os.path.dirname(path))
         if not content.endswith('\n'):
             content += '\n'
-        with codecs.open(path, "wb+", "utf8") as fd:
-            if one_file:
-                fd.write("////\n")
-                fd.write(write_metadata(metadata))
-                fd.write("////\n")
+        with io.open(path, "w+", encoding="utf8") as fd:
+            if onefile:
+                fd.write(write_metadata(metadata, comment_wrap=('///', '///'), site=self.site, compiler=self))
             fd.write(content)
diff --git a/plugins/asciidoc/conf.py.sample b/plugins/asciidoc/conf.py.sample
index 1dd5d3aa6..b8fda52f0 100644
--- a/plugins/asciidoc/conf.py.sample
+++ b/plugins/asciidoc/conf.py.sample
@@ -1,11 +1,14 @@
 # Add the asciidoc compiler to your COMPILERS dict.
-COMPILERS["asciidoc"] = ('.asc',)
+COMPILERS["asciidoc"] = ['.asc']
 
 # Add asciidoc files to your POSTS, PAGES
 POSTS = POSTS + (("posts/*.asc", "posts", "post.tmpl"),)
-PAGES = PAGES + (("stories/*.asc", "posts", "post.tmpl"),)
+PAGES = PAGES + (("pages/*.asc", "pages", "page.tmpl"),)
 
 # You can choose what command to use for processing.
 # For example, you can replace asciidoc with asciidoctor
 # Or use the full path to the program.
 # ASCIIDOC_BINARY = "asciidoc"
+
+# Specify options to the asciidoc compiler (as a string).
+# ASCIIDOC_OPTIONS = ""
diff --git a/plugins/asciidoc/requirements-nonpy.txt b/plugins/asciidoc/requirements-nonpy.txt
index 288ae9dc7..060eac8eb 100644
--- a/plugins/asciidoc/requirements-nonpy.txt
+++ b/plugins/asciidoc/requirements-nonpy.txt
@@ -1 +1,2 @@
-AsciiDoc::http://www.methods.co.nz/asciidoc/
+AsciiDoc::https://asciidoc.org/INSTALL.html
+Asciidoctor (alternative)::https://asciidoctor.org/
diff --git a/plugins/documentation/documentation/__init__.py b/plugins/documentation/documentation/__init__.py
index fcc69c2a3..d5482e013 100644
--- a/plugins/documentation/documentation/__init__.py
+++ b/plugins/documentation/documentation/__init__.py
@@ -233,21 +233,21 @@ def create_docs(self):
                 clazz.name = clazz.name[:-1]
 
             clazz.detailed_inline_description = relative_urls(clazz.detailed_inline_description)
-            clazz.detailed_inline_description = markdown(clazz.detailed_inline_description, md_extensions)
+            clazz.detailed_inline_description = markdown(clazz.detailed_inline_description, extensions=md_extensions)
             clazz.detailed_inline_description = of_classes_to_links(clazz.detailed_inline_description, classes_simple_name, module_lookup)
 
             clazz.reference = relative_urls(clazz.reference)
-            clazz.reference = markdown(clazz.reference, md_extensions)
+            clazz.reference = markdown(clazz.reference, extensions=md_extensions)
             clazz.reference = of_classes_to_links(clazz.reference, classes_simple_name, module_lookup)
 
             # methods in class
             for function in clazz.function_list:
                 function.description = relative_urls(function.description)
-                function.description = markdown(function.description, md_extensions)
+                function.description = markdown(function.description, extensions=md_extensions)
                 function.description = of_classes_to_links(function.description, classes_simple_name, module_lookup)
 
                 function.inlined_description = relative_urls(function.inlined_description)
-                function.inlined_description = markdown(function.inlined_description, md_extensions)
+                function.inlined_description = markdown(function.inlined_description, extensions=md_extensions)
                 function.inlined_description = of_classes_to_links(function.inlined_description, classes_simple_name, module_lookup)
                 for lang in self.kw['translations']:
                     content_js[lang] += method_to_js(function, clazz, self.site, lang)
@@ -263,11 +263,11 @@ def filter_out_empty(class_name):
             functions_file = markdown_file.getfunctionsfile(clazz.name)
             for function in functions_file.function_list:
                 function.description = relative_urls(function.description)
-                function.description = markdown(function.description, md_extensions)
+                function.description = markdown(function.description, extensions=md_extensions)
                 function.description = of_classes_to_links(function.description, classes_simple_name, module_lookup)
 
                 function.inlined_description = relative_urls(function.inlined_description)
-                function.inlined_description = markdown(function.inlined_description, md_extensions)
+                function.inlined_description = markdown(function.inlined_description, extensions=md_extensions)
                 function.inlined_description = of_classes_to_links(function.inlined_description, classes_simple_name, module_lookup)
                 for lang in self.kw['translations']:
                     content_js[lang] += function_to_js(function, functions_file, self.site, lang)
@@ -337,11 +337,11 @@ def filter_out_empty(class_name):
 
             for function in functions_file.function_list:
                 function.description = relative_urls(function.description)
-                function.description = markdown(function.description, md_extensions)
+                function.description = markdown(function.description, extensions=md_extensions)
                 function.description = of_classes_to_links(function.description, classes_simple_name, module_lookup)
 
                 function.inlined_description = relative_urls(function.inlined_description)
-                function.inlined_description = markdown(function.inlined_description, md_extensions)
+                function.inlined_description = markdown(function.inlined_description, extensions=md_extensions)
                 function.inlined_description = of_classes_to_links(function.inlined_description, classes_simple_name, module_lookup)
                 for lang in self.kw['translations']:
                     content_js[lang] += function_to_js(function, functions_file, self.site, lang)
@@ -394,7 +394,7 @@ def filter_out_empty(class_name):
                         module_intro_file = open(module_intro)
                         module_intro_content = module_intro_file.read()
                         module_subtitles[module] = module_intro_content.splitlines()[0].strip('##').strip(' ')
-                        module_intro_content = markdown(module_intro_content, md_extensions)
+                        module_intro_content = markdown(module_intro_content, extensions=md_extensions)
                         for lang in self.kw['translations']:
                             context = {}
                             context["site_url"] = self.site.config["SITE_URL"]
@@ -440,7 +440,7 @@ def filter_out_empty(class_name):
             for key in self.site.GLOBAL_CONTEXT.keys():
                 if isinstance(self.site.GLOBAL_CONTEXT[key], str):
                    docs_intro = docs_intro.replace('${' + key + '}', self.site.GLOBAL_CONTEXT[key])
-            docs_intro = markdown(docs_intro, md_extensions)
+            docs_intro = markdown(docs_intro, extensions=md_extensions)
             context = {}
             context["lang"] = lang
             context["site_url"] = self.site.config["SITE_URL"]
diff --git a/plugins/tutorials/tutorials.plugin b/plugins/tutorials.plugin
similarity index 100%
rename from plugins/tutorials/tutorials.plugin
rename to plugins/tutorials.plugin
diff --git a/plugins/tutorials/tutorials/__init__.py b/plugins/tutorials/__init__.py
similarity index 100%
rename from plugins/tutorials/tutorials/__init__.py
rename to plugins/tutorials/__init__.py
diff --git a/plugins/tutorials/tutorials/asciidoc_template/__init__.py b/plugins/tutorials/asciidoc_template/__init__.py
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/__init__.py
rename to plugins/tutorials/asciidoc_template/__init__.py
diff --git a/plugins/tutorials/tutorials/asciidoc_template/asciidoc b/plugins/tutorials/asciidoc_template/asciidoc
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/asciidoc
rename to plugins/tutorials/asciidoc_template/asciidoc
diff --git a/plugins/tutorials/tutorials/asciidoc_template/asciidoc.conf b/plugins/tutorials/asciidoc_template/asciidoc.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/asciidoc.conf
rename to plugins/tutorials/asciidoc_template/asciidoc.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/asciidocapi.py b/plugins/tutorials/asciidoc_template/asciidocapi.py
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/asciidocapi.py
rename to plugins/tutorials/asciidoc_template/asciidocapi.py
diff --git a/plugins/tutorials/tutorials/asciidoc_template/asciidocc b/plugins/tutorials/asciidoc_template/asciidocc
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/asciidocc
rename to plugins/tutorials/asciidoc_template/asciidocc
diff --git a/plugins/tutorials/tutorials/asciidoc_template/docbook45.conf b/plugins/tutorials/asciidoc_template/docbook45.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/docbook45.conf
rename to plugins/tutorials/asciidoc_template/docbook45.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/escape.py b/plugins/tutorials/asciidoc_template/escape.py
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/escape.py
rename to plugins/tutorials/asciidoc_template/escape.py
diff --git a/plugins/tutorials/tutorials/asciidoc_template/help.conf b/plugins/tutorials/asciidoc_template/help.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/help.conf
rename to plugins/tutorials/asciidoc_template/help.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/html4.conf b/plugins/tutorials/asciidoc_template/html4.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/html4.conf
rename to plugins/tutorials/asciidoc_template/html4.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-de.conf b/plugins/tutorials/asciidoc_template/lang-de.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-de.conf
rename to plugins/tutorials/asciidoc_template/lang-de.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-en.conf b/plugins/tutorials/asciidoc_template/lang-en.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-en.conf
rename to plugins/tutorials/asciidoc_template/lang-en.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-es.conf b/plugins/tutorials/asciidoc_template/lang-es.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-es.conf
rename to plugins/tutorials/asciidoc_template/lang-es.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-fr.conf b/plugins/tutorials/asciidoc_template/lang-fr.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-fr.conf
rename to plugins/tutorials/asciidoc_template/lang-fr.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-hu.conf b/plugins/tutorials/asciidoc_template/lang-hu.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-hu.conf
rename to plugins/tutorials/asciidoc_template/lang-hu.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-it.conf b/plugins/tutorials/asciidoc_template/lang-it.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-it.conf
rename to plugins/tutorials/asciidoc_template/lang-it.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-pt-BR.conf b/plugins/tutorials/asciidoc_template/lang-pt-BR.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-pt-BR.conf
rename to plugins/tutorials/asciidoc_template/lang-pt-BR.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-ru.conf b/plugins/tutorials/asciidoc_template/lang-ru.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-ru.conf
rename to plugins/tutorials/asciidoc_template/lang-ru.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/lang-uk.conf b/plugins/tutorials/asciidoc_template/lang-uk.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/lang-uk.conf
rename to plugins/tutorials/asciidoc_template/lang-uk.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/latex.conf b/plugins/tutorials/asciidoc_template/latex.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/latex.conf
rename to plugins/tutorials/asciidoc_template/latex.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/testasciidoc.conf b/plugins/tutorials/asciidoc_template/testasciidoc.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/testasciidoc.conf
rename to plugins/tutorials/asciidoc_template/testasciidoc.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/text.conf b/plugins/tutorials/asciidoc_template/text.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/text.conf
rename to plugins/tutorials/asciidoc_template/text.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/wordpress.conf b/plugins/tutorials/asciidoc_template/wordpress.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/wordpress.conf
rename to plugins/tutorials/asciidoc_template/wordpress.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/xhtml11-quirks.conf b/plugins/tutorials/asciidoc_template/xhtml11-quirks.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/xhtml11-quirks.conf
rename to plugins/tutorials/asciidoc_template/xhtml11-quirks.conf
diff --git a/plugins/tutorials/tutorials/asciidoc_template/xhtml11.conf b/plugins/tutorials/asciidoc_template/xhtml11.conf
similarity index 100%
rename from plugins/tutorials/tutorials/asciidoc_template/xhtml11.conf
rename to plugins/tutorials/asciidoc_template/xhtml11.conf
diff --git a/serve.sh b/serve.sh
deleted file mode 100755
index cf1161c5b..000000000
--- a/serve.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-source nikola/bin/activate
-nikola serve
-
diff --git a/themes/openframeworks/parent b/themes/openframeworks/parent
index dc199ee36..1e7e49224 100644
--- a/themes/openframeworks/parent
+++ b/themes/openframeworks/parent
@@ -1 +1 @@
-bootstrap3
+bootstrap4