{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Table of Contents

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction \n", "\n", "[Nikola](https://getnikola.com/) is a good way to build a static website/blog. It's versatile, powerful and open-source. There are other options such as [Hugo](https://gohugo.io/), [Pelican](https://docs.getpelican.com/en/stable/quickstart.html), and [Sphinx](https://github.com/sphinx-doc/sphinx). After reviewing their pros and cons, I decided to use Nikola mainly because of its Jupyter and Matlab-kernel integration.\n", "\n", "There is a lot of good material on the internet about installing and using Nikola, but I thought it will be useful to show my methodology from the perspective of someone who has never used Anaconda, Jupyter and Nikola.\n", "\n", "\n", "Nevertheless, here is a list of the official documentation and good tutorials I recommend:\n", "\n", "- [Nikola Getting Started](https://getnikola.com/getting-started.html).\n", "- [Nikola Handbook](https://getnikola.com/handbook.html#).\n", "- [Complete and comprehensive tutorial](https://randlow.github.io/posts/python/create-nikola-coding-blog/).\n", "- [Compact tutorial](https://jiaweizhuang.github.io/blog/nikola-guide/).\n", "- [For extra customization](https://notes.mikejarrett.ca/optimizing-your-nikola-blog-for-jupyter-notebooks/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Pre-requisites\n", "\n", "- [Anaconda](https://www.anaconda.com/).\n", "- [Jupyter Notebook](https://jupyter.org/).\n", "- [Matlab-kernel (jmatlab)](https://github.com/Calysto/matlab_kernel).\n", "- [VSCode](https://code.visualstudio.com/), but you can use any editor you like.\n", "- [GitHub pages](https://pages.github.com/).\n", "- Knowledge in HTML, CSS, JS, Matlab, Python, Git, Markdown, and reStructedText." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Configure VSCode\n", "\n", "- Install the [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python).\n", "- Make sure `Python › Data Science: Allow Import From Notebook` setting is enabled." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Create a new environment with Anaconda or Conda \n", "\n", "- Download and install [Anaconda](https://www.anaconda.com/products/individual#Downloads) or [Miniconda](https://repo.anaconda.com/miniconda/). It's your choice.\n", "- After the installation is complete, make sure the following are listed in you Windows `system path variables`:\n", " ```\n", " C:\\Users\\\\anaconda3\\\n", " C:\\Users\\\\anaconda3\\condabin\n", " C:\\Users\\\\anaconda3\\Library\n", " C:\\Users\\\\anaconda3\\Scripts\n", " ```\n", "- To check where is installed anaconda, run the following:\n", " ```\n", " where conda\n", " ```\n", "- In Anaconda Navigator, create a new environment named `jmatlabNikola` with `Python 3.8`.\n", "- Or open terminal (**recommended**) and run\n", " ```\n", " conda create --name jmatlabNikola python=3.8\n", " ```\n", "- A new folder will be created inside `C:\\Users\\\\.conda\\envs\\`\n", "\n", "**Why Python 3.8?**\n", "\n", "[Matlab engine](https://www.mathworks.com/help/matlab/matlab-engine-for-python.html) is compatible with Python 2.7 and 3.x. Version 3.7 is for Matlab 2019+, 3.6 is for Matlab 2018+, and 3.8 is for 2022a.\n", "\n", "**Why a new environment?** \n", "\n", "Anaconda (conda) is a powerful **package management platform** that allows you to install any **self-contained** workspace (environment) with different kernels and libraries. For example, let's say I have two environments:\n", "\n", "- `jmatlabNikola`: composed by Python 3.8, Jupyter Notebook, jmatlab, and Nikola.\n", "- `openCV_TF`: composed by Python 3.7, OpenCV, and TensorFlow.\n", " \n", "So, let's say I want to write a post, I should do the following: \n", "\n", "- Run `activate jmatlabNikola` → it switches to Python 3.8 (you can check with `python --version`). \n", " ```\n", " (jmatlabNikola) C:\\Users\\\\blog>python --version\n", " Python 3.8.13 :: Anaconda, Inc. \n", " ```\n", " Any post I write will be compiled by this environment only. None of the libraries from the other environment(s) will be available. \n", "\n", "But if I want to work with OpenCV:\n", "\n", "- Run `activate openCV_TF` → it switches to Python 3.7. The kernel and libraries of `jmatlabNikola` are not available and won't get mixed with this environment.\n", " ```\n", " (openCV_TF) C:\\Users\\\\ML_project>python --version\n", " Python 3.7.6 :: Anaconda, Inc.\n", " ```\n", "\n", "**Notes**\n", "\n", "- Don't use the `base` environment of Anaconda if you want to test packages. Use it as a reference because it's the default environment for your OS.\n", "- If you already have Python installed, you can still use Anaconda without any problems. Just make sure the `Anaconda python path` is configured in VSCode. \n", "- Your work files and folders could be anywhere on your hard drive, but don't create them inside the environment folders." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Install Jupyter Notebook, Nikola and jmatlab\n", "\n", "- Open terminal in `cd \"C:\\Users\\\\.conda\\envs\\jmatlabNikola\"`\n", "- Install Jupyter Notebook and nbextensions:\n", " - Install Jupyter.\n", " ``` \n", " pip install notebook\n", " ```\n", " - Install the [`nbextensions`](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html#install-the-python-package).\n", " ```\n", " pip install jupyter_contrib_nbextensions\n", " jupyter contrib nbextension install --user\n", " ```\n", " - Install the Jupyter nbextension configurator\n", " ```\n", " pip install jupyter_nbextensions_configurator\n", " jupyter nbextensions_configurator enable --user\n", " ```\n", " - Run Jupyter Notebook by command line to check it was installed correctly with the nbextensions. \n", " ```\n", " jupyter notebook\n", " ```\n", " - It will open the browser in http://localhost:8888 where I recommend to enable the following nbextensions:\n", " - (some) LaTex environments for Jupyter\n", " - Equation Auto Numbering\n", " - CodeMirror mode extensions -> Matlab/Octave highlighting\n", " - Table of Contents (2) -> auto ToC\n", "- Install Nikola.\n", " ```\n", " pip install Nikola[extras]\n", " ```\n", "- Install Matlab-kernel.\n", " ```\n", " pip install matlab_kernel\n", " python -m matlab_kernel install --user\n", " ```\n", "- Check installed kernels. \n", " ```\n", " jupyter kernelspec list\n", " ```\n", " You'll see something like this.\n", " ```\n", " Available kernels:\n", " matlab C:\\Users\\\\AppData\\Roaming\\jupyter\\kernels\\matlab\n", " matlab C:\\Users\\\\.conda\\envs\\jmatlabNikola\\share\\jupyter\\kernels\\matlab_connect\n", " python3 C:\\Users\\\\.conda\\envs\\jmatlabNikola\\share\\jupyter\\kernels\\python3\n", " ```\n", "\n", "** Config Matlab **\n", "\n", "- Open terminal as **administrator**\n", " ```\n", " activate jmatlabNikola\n", " ```\n", "- Go to `cd \"C:\\Program Files\\MATLAB\\R2022a\\extern\\engines\\python\"`\n", "- Install the Python engine.\n", " ```\n", " python setup.py install\n", " ```\n", "\n", "\n", "Done!, now you have everything what it's needed in your environment. \n", "\n", "**Notes**\n", "\n", "- Make sure you activate `jmatlabNikola` environment with admin rights to install `matlab_kernel`.\n", "- If you have doubts about the Python kernel, check with `python --version` every time you activate an environment.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Create a Nikola demo site\n", "\n", "- Create a new folder called `blog` anywhere you like except inside the `jmatlabNikola` environment.\n", "- Open terminal inside your `blog` folder.\n", "- Activate the environment. \n", " ```\n", " activate jmatlabNikola\n", " ```\n", "- Initialize a demo, and fill its content.\n", " ```\n", " nikola init --demo\n", " ```\n", "- Build (generate) the HTML files of the site.\n", " ```\n", " nikola build\n", " ```\n", "- View on your browser. It will open the localhost on `http://127.0.0.1:8000`.\n", " ```\n", " nikola serve -b\n", " ```\n", "- Automatically `build` and `serve` your site if you want to see all changes constantly (**recommended**). \n", " ```\n", " nikola auto\n", " ```\n", "- Clean `output/` content whenever you remove any of content manually from your `blog` folder. Use it before `build` command.\n", " ```\n", " nikola check -f --clean-files\n", " ```\n", "- Press `ctrl+c` to stop the server.\n", "\n", "**Note**\n", "\n", "\n", "At this point you can deploy on `Github Pages`. Just go to the section **Compile your website/blog and deploy on GitHub pages** and follow the instructions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a new post and new page\n", "\n", "- Create a new post and new page. By default, they are created in `.rst` format.\n", " ```\n", " nikola new_post\n", " nikola new_page\n", " ``` \n", "- Other posts on different formats. For `-f ipynb`, it is needed extra configuration, you'll see that later.\n", " ```\n", " nikola new_post -f md\n", " nikola new_post -f rst\n", " nikola new_post -f html\n", " nikola new_post -f ipynb\n", " ```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a clean Nikola site\n", "\n", "Same as before but run `nikola init` instead of `nikola init --demo`.\n", "\n", "That's it!. Navigate through the files and see what Nikola has done with the demo or the clean version." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Nikola directories\n", "\n", "Although, most of them are self-explained, they can be categorized in three types:\n", "\n", "- Content: `files`, `galleries`, `images`, `listings`, `pages`, `posts`.\n", "- Customization: `plugins`, `templates`, `themes`.\n", "- Visible output: `output`. Here, all your content is parsed to `.html` to be visible in any web hosting service such as GitHub pages.\n", " ```bash\n", " ../__pycache__\n", " ../cache \n", " ../files # all the files of your blog, e.g. pdf, videos, etc.\n", " ../galleries # galleries of images.\n", " ../images # images of your website.\n", " ../listings # code files, e.g. .py, .tex, .m, .cpp, etc.\n", " ../output # the root directory of your website. \n", " ../pages # stores index.html, blog.html, home.html, about-me.html. \n", " ../plugins # additional plugins.\n", " ../posts # stores all your posts, .md, .html, .ipynb, and .rst\n", " ../templates # additional templates. \n", " ../themes # additional themes.\n", " ```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Configure a non-blog Nikola site \n", "\n", "From now on, we will configure Nikola using `conf.py`, located in your root directory.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create the index page and bio page\n", "\n", "- First, create both pages using the terminal.\n", " ```bash\n", " nikola new_page --title=\"index\"\n", " nikola new_page --title=\"bio\"\n", " ```\n", "- Add them to the navigation links.\n", " ```python\n", " NAVIGATION_LINKS = {\n", " DEFAULT_LANG: (\n", " (\"/index.html\", \"Home\"),\n", " (\"/bio/index.html\", \"Bio\"),\n", " ...\n", " ),\n", " ```\n", "- Add any other page, just make sure to add them on the navigation list, e.g. about-me, contact, etc.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Use Jupyter Notebooks\n", "\n", "- By default, Nikola uses the **blog** configuration.\n", " ```python\n", " POSTS = (\n", " (\"posts/*.rst\", \"posts\", \"post.tmpl\"),\n", " (\"posts/*.md\", \"posts\", \"post.tmpl\"),\n", " (\"posts/*.txt\", \"posts\", \"post.tmpl\"),\n", " (\"posts/*.html\", \"posts\", \"post.tmpl\"),\n", " (\"posts/*.ipynb\", \"posts\", \"post.tmpl\"),\n", " )\n", " PAGES = (\n", " (\"pages/*.rst\", \"pages\", \"page.tmpl\"),\n", " (\"pages/*.md\", \"pages\", \"page.tmpl\"),\n", " (\"pages/*.txt\", \"pages\", \"page.tmpl\"),\n", " (\"pages/*.html\", \"pages\", \"page.tmpl\"),\n", " (\"pages/*.ipynb\", \"pages\", \"page.tmpl\"), \n", " )\n", " ```\n", "- Change it to the [**non-blog** configuration](https://getnikola.com/creating-a-site-not-a-blog-with-nikola.html).\n", " ```python\n", " POSTS = (\n", " (\"posts/*.rst\", \"blog\", \"post.tmpl\"),\n", " (\"posts/*.md\", \"blog\", \"post.tmpl\"),\n", " (\"posts/*.txt\", \"blog\", \"post.tmpl\"),\n", " (\"posts/*.html\", \"blog\", \"post.tmpl\"),\n", " (\"posts/*.ipynb\", \"blog\", \"post_ipynb.tmpl\"),\n", " )\n", " PAGES = (\n", " (\"pages/*.rst\", \"\", \"page.tmpl\"),\n", " (\"pages/*.md\", \"\", \"page.tmpl\"),\n", " (\"pages/*.txt\", \"\", \"page.tmpl\"),\n", " (\"pages/*.html\", \"\", \"page.tmpl\"),\n", " (\"pages/*.ipynb\", \"\", \"post_ipynb.tmpl\"),\n", " )\n", " # And to avoid a conflict because blogs try to generate /index.html\n", " INDEX_PATH = \"blog\"\n", " ```\n", "- Check if `.ipynb` is listed in the compilers section.\n", " ```python\n", " COMPILERS = {\n", " \"rest\": ['.rst', '.txt'],\n", " \"markdown\": ['.md', '.mdown', '.markdown'],\n", " \"textile\": ['.textile'],\n", " \"txt2tags\": ['.t2t'],\n", " \"bbcode\": ['.bb'],\n", " \"wiki\": ['.wiki'],\n", " \"ipynb\": ['.ipynb'],\n", " \"html\": ['.html', '.htm'],\n", " ...\n", " ```\n", "- If you `build` and `serve` the site, it will give you an error of `\"missing post_ipynb.tmpl\"`. We'll create it on the next section.\n", "- Change `post_ipynb.tmpl` to `post.tmpl`, and run `nikola auto` to see the default Jupyter Notebook style." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create the `post_ipynb.tmpl` template\n", "\n", "- Create a new theme.\n", " ```\n", " nikola theme --new=themeBlog --parent=bootstrap4 --engine=mako\n", " ```\n", "- Copy `post.tmpl` template from the parent theme. \n", " ```\n", " nikola theme --copy-template=post.tmpl\n", " ```\n", "- Move it to the `/themes/themeBlog/templates/post_ipynb.tmpl` folder and rename it as `post_ipynb.tmpl`\n", "- Add the following on the extra head section.\n", " ```html\n", " <%block name=\"extra_head\">\n", " ... \n", " \n", " \n", " ```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create the `post_ipynb.css` \n", "\n", "Create the file inside `/themes/themeBlog/assets/css/post_ipynb.css` folder and copy the following.\n", "\n", "```css\n", "div.prompt {\n", " padding: 0.6em;\n", " font-size: 13px;\n", " background-color: #ffffff;\n", " margin-right: 0em;\n", " -webkit-border-radius: 3px;\n", " -moz-border-radius: 3px;\n", " border-radius: 3px;\n", "}\n", " \n", "div.output_prompt {\n", " /* 5px right shift to account for margin in parent container */\n", " margin: 0 5px 0 0px;\n", "}\n", " \n", " div.output_area pre {\n", " font-size: 13px;\n", "}\n", " \n", "div.text_cell_render {\n", " padding: 0px;\n", " color: #333333;\n", "}\n", " \n", ".rendered_html p {\n", " text-align: left;\n", "}\n", " \n", ".rendered_html ul {\n", " margin: 0 0 12px 25px;\n", "}\n", " \n", ".rendered_html :visited {\n", " text-decoration: none;\n", "}\n", " \n", ".rendered_html :link {\n", " text-decoration: none;\n", " }\n", " \n", ".rendered_html pre, .rendered_html code {\n", " background-color: #eeeeee;\n", " margin: 1em 0em;\n", " font-size: 14px;\n", "}\n", " \n", ".rendered_html pre {\n", " padding-left: 0.5em;\n", " padding-right: 0.5em;\n", " padding-top: 0.05em;\n", " padding-bottom: 0.05em;\n", "}\n", " \n", ".page-content > .content p {\n", " margin: 0 0 0px;\n", "}\n", "\n", "\n", "div.input {\n", " border: none;\n", " background-color: none;\n", "}\n", "\n", "/* set a max-width for horizontal fluid layout and make it centered */\n", ".body-content {\n", " margin-right: auto;\n", " margin-left: auto;\n", " max-width: 100%; /* or 950px */\n", "}\n", " \n", "/* Widens image-containing divs so that image is full body width */\n", "div.output_subarea { \n", " max-width: 100%;\n", "}\n", "```\n", "\n", "Change it at pleasure. In my case, among other minor changes, I set the `background-color: #ffffff` to get rid off the left gray ribbon on each cell." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clean version of `post_ipynb.css`\n", "\n", "```css\n", "div.prompt {\n", " display: none;\n", "}\n", "\n", "div.input {\n", " border: none;\n", " background-color: none;\n", "}\n", "\n", "div.input * {\n", " background-color: none;\n", "}\n", "\n", "/* set a max-width for horizontal fluid layout and make it centered */\n", ".body-content {\n", " margin-right: auto;\n", " margin-left: auto;\n", " max-width: 100%; /* or 950px */\n", "}\n", "\n", "/* Widens image-containing divs so that image is full body width */\n", "div.output_subarea {\n", " max-width: 100%;\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Use your custom theme\n", "\n", "Once you are happy with the changes.\n", "\n", "- Enable your theme.\n", " ```python\n", " THEME = \"themeBlog\"\n", " ```\n", "- Create a Jupyter Notebook post, and start editing with VSCode.\n", " ```\n", " nikola new_post -f ipynb --title=\"Jupyter-notebook-test\"\n", " ```\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Extra configurations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Output `files` folder location\n", "\n", "Your documents saved in the `files` folder will be copied to `/output/files` instead of the root folder, which is the default location.\n", "```python\n", "FILES_FOLDERS = {'files': 'files'} \n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Avoid deploying draft posts\n", "\n", "If you don't want to deploy a draft post.\n", "\n", "- Add to the metadata post.\n", " ```\n", " .. status: draft\n", " ```\n", "- Set in `conf.py`\n", " ```python\n", " DEPLOY_DRAFTS = False\n", " ```\n", "It will be built and seen on your localhost but won't be deployed to GitHub. Also, when you run `nikola github_deploy`, the draft post is removed from the `output` folder. \n", "\n", "By default the metadata has no `status` line or is set to:\n", "```\n", ".. status: published \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Enable single Archive\n", "\n", "Create one large archive instead of per-year.\n", "```python\n", "CREATE_SINGLE_ARCHIVE = True\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Favicon\n", "\n", "Add a favicon to your site.\n", "```python\n", "FAVICONS = (\n", " (\"icon\", \"/files/blogFavicon.ico\", \"128x128\"),\n", ")\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## License\n", "\n", "Add a license to your content.\n", "```html\n", "LICENSE = \"\"\"\n", "\n", "\"Creative\"\"\"\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Header\n", "\n", "Add [FontAwesone](fontawesome.com/) and [Academic Icons](https://jpswalsh.github.io/academicons/) to use in the footer content.\n", "```html\n", "EXTRA_HEAD_DATA = '''\n", " \n", " \n", "'''\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Footer\n", "\n", "Customize the footer as you like. A good way is to show your social network profiles.\n", "\n", "```html\n", "CONTENT_FOOTER = '''\n", "
\n", "

\n", " \n", " \">\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "

\n", "

\n", " {license} Contents © {date} {author} - Powered by Nikola\n", "

\n", "
\n", "'''\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Google search form (button)\n", "\n", "Add the following\n", "```html\n", "SEARCH_FORM = \"\"\"\n", "\n", "
\n", "
\n", " \n", " \n", " \n", "
\n", "
\n", "\n", "\"\"\" % SITE_URL\n", "```\n", "\n", "**Notes**\n", "- You may find that `conf.py` uses [Glyphicon](https://www.glyphicons.com), but recently Bootstrap 4+ changed it to [FontAwesome](https://stackoverflow.com/questions/32612690/bootstrap-4-glyphicons-migration), so Glyphicon is not available anymore.\n", "- Change `form-group` to `input-group`.\n", "- More configurations with [Bootstrap 4 demo Icon inputs](https://www.codeply.com/go/ioPsDfyCBc).\n", "- [Duckduckgo](https://duckduckgo.com/) is also available in the `conf.py` file." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Index your site using Google Search Console\n", "\n", "To make sure your site can be find through Google, index it with Google Search Console. You can also do it using your Google Analytics account if you have one, but the easiest way is using HTML meta tag, [official documentation](https://support.google.com/webmasters/answer/9008080#html_verification).\n", "\n", "- Go to [Google Search Console website](https://search.google.com/search-console/about).\n", "- Select `URL prefix` as property type, and introduce your url `https://.github.io`\n", " \"Google \n", "- On the Verify ownership window, select HTML tag\n", " \"Google \n", "- Copy the **unique** given code to\n", "```html\n", "EXTRA_HEAD_DATA = '''\n", " ...\n", " \n", "'''\n", "```\n", "- Build and deploy your site.\n", "- Select `Verify`, and you will see\n", " \"Google \n", "- Finally, add your `sitemap.xml` by going to **Google Search Console menu/Sitemaps**, and **Submit** `https://.github.io/sitemap.xml`. You can verify this file is generated automatically with Nikola, and is located inside the output folder.\n", "\n", " \n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Google Analytics\n", "In order to use the new version 4, follow the steps.\n", "\n", "- Go to [Google Analytics](https://analytics.google.com) and create an account.\n", "- Go to Admin an create a new **Property**, prefarable with the name of you site.\n", "- Select your industry category and business size.\n", "- Select the **Property** and add a new **Data Stream**.\n", "- Select **Web** and put the **url of your site**.\n", "- Once created, select the **Web stream details** and copy the **MEASUREMENT ID** or the **Global Site Tag (gtag.js)** script.\n", "- Go to `conf.py` and add the following. \n", "```html\n", "BODY_END = '''\n", " ...\n", "\n", " \n", " \n", " \n", "'''\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Disqus\n", "\n", "- Create an account on [Disqus](https://disqus.com/).\n", " - Create a new site.\n", " - Choose a `disqus_shortname`, e.g. `github_user_name`. I recommend not to use `.github.io`\n", " - Add your blog site `.github.io`.\n", " - Choose *'Basic Plan'* \n", " - Skip instructions on the *'Select Platform'* section.\n", "- Finally, enable the following on the Nikola `conf.py`\n", " ```python\n", " COMMENT_SYSTEM = \"disqus\"\n", " COMMENT_SYSTEM_ID = \"\"\n", " ```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Config the sticky menu\n", "\n", "You can set the navigation bar sticks on the top as you scroll down the page.\n", "\n", "- Copy the parent base template.\n", " ```bash\n", " nikola theme --copy-template=base.tmpl\n", " ```\n", "- Move it to `/themes/themeBlog/templates/base.tmpl` and add the following.\n", " ```html\n", " \n", "