A new Riff-radio.org site with a static approach.

internals.rst 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. .. title: Nikola Internals
  2. .. slug: internals
  3. .. date: 2012-03-30 23:00:00 UTC-03:00
  4. .. tags:
  5. .. link:
  6. .. description:
  7. .. author: The Nikola Team
  8. .. class:: lead
  9. When trying to guide someone into adding a feature in Nikola, it hit me that
  10. while the way it's structured makes sense **to me** it is far from obvious.
  11. So, this is a short document explaining what each piece of Nikola does and
  12. how it all fits together.
  13. Nikola is a Pile of Plugins
  14. Most of Nikola is implemented as plugins using `Yapsy <http://yapsy.sourceforge.net/>`_.
  15. You can ignore that they are plugins and just think of them as regular python
  16. modules and packages with a funny little ``.plugin`` file next to them.
  17. So, 90% of the time, what you want to do is either write a new plugin or extend
  18. an existing one.
  19. There are several kinds of plugins, all implementing interfaces defined in
  20. ``nikola/plugin_categories.py`` and documented in
  21. `Extending Nikola <https://getnikola.com/extending.html>`_
  22. If your plugin has a dependency, please make sure it doesn't make Nikola
  23. throw an exception when the dependency is missing. Try to fail gracefully
  24. with an informative message.
  25. Commands are plugins
  26. When you use ``nikola foo`` you are using the plugin ``command/foo``. Those are
  27. used to extend Nikola's command line. Their interface is defined in the ``Command``
  28. class. They take options and arguments and do whatever you want, so go wild.
  29. The ``build`` command is special
  30. The ``build`` command triggers a whole lot of things, and is the core of Nikola
  31. because it's the one that you use to build sites. So it deserves its own section.
  32. The Build Command
  33. -----------------
  34. Nikola's goal is similar, deep at heart, to a Makefile. Take sources, compile them
  35. into something, in this case a website. Instead of a Makefile, Nikola uses
  36. `doit <https://pydoit.org>`_.
  37. Doit has the concept of "tasks". The 1 minute summary of tasks is that they have:
  38. actions
  39. What the task **does**. For example, convert a markdown document into HTML.
  40. dependencies
  41. If this file changes, then we need to redo the actions. If this configuration
  42. option changes, redo it, etc.
  43. targets
  44. Files that the action generates. No two actions can have the same targets.
  45. basename:name
  46. Each task is identified by either a name or a basename:name pair.
  47. .. sidebar:: More about tasks
  48. If you ever want to do your own tasks, you really should read the doit
  49. `documentation on tasks <https://pydoit.org/tasks.html>`_.
  50. Notably, by default doit redirects ``stdout`` and ``stderr``. To get a
  51. proper PDB debugging shell, you need to use doit's own
  52. `set_trace <https://pydoit.org/tools.html#set-trace>`_ function.
  53. So, what Nikola does, when you use the build command, is to read the
  54. configuration ``conf.py`` from the current folder, instantiate
  55. the ``Nikola`` class, and have it generate a whole list of tasks for doit
  56. to process. Then doit will decide which tasks need doing, and do them, in
  57. the right order.
  58. The place where the tasks are generated is in ``Nikola.gen_tasks``, which collects tasks
  59. from all the plugins inheriting ``BaseTask``, massages them a bit, then passes them
  60. to doit.
  61. So, if you want things to happen on ``build`` you want to create a Task plugin, or extend
  62. one of the existing ones.
  63. .. sidebar:: Tests
  64. While Nikola is not a hardcore TDD project, we like tests. So, please add them if you can.
  65. You can write unit tests or integration tests. (Doctests are not supported
  66. anymore due to fragility.)
  67. Posts and Pages
  68. ---------------
  69. Nikola has a concept of posts and pages. Both are more or less the same thing, except
  70. posts are added into RSS feeds and pages are not. All of them are in a list called
  71. "the timeline" formed by objects of class ``Post``.
  72. When you are creating a task that needs the list of posts and/or pages (for example,
  73. the RSS creation plugin) on task execution time, your plugin should call ``self.site.scan_posts()``
  74. in ``gen_tasks`` to ensure the timeline is created and available in
  75. ``self.site.timeline``. You should not modify the timeline, because it will cause consistency issues.
  76. .. sidebar:: scan_posts
  77. The ``Nikola.scan_posts`` function can be used in plugins to force the
  78. timeline creation, for example, while creating the tasks.
  79. Your plugin can use the timeline to generate "stuff" (technical term). For example,
  80. Nikola comes with plugins that use the timeline to create a website (surprised?).
  81. The workflow included with nikola is as follows (incomplete!):
  82. #. The post is assigned a compiler based on its extension and the ``COMPILERS`` option.
  83. #. The compiler is applied to the post data and a "HTML fragment" is produced. That
  84. fragment is stored in a cache (the ``posts`` plugin).
  85. #. The configured theme has templates (and a template engine), which are applied to the post's
  86. HTML fragment and metadata (the ``pages`` plugin).
  87. #. The original sources for the post are copied to some accessible place (the ``sources`` plugin).
  88. #. If the post is tagged, some pages and RSS feeds for each tag are updated (the ``tags`` plugin).
  89. #. If the post is new, it's included in the blog's RSS feed (the ``rss`` plugin).
  90. #. The post is added in the right place in the index pages for the blog (the ``indexes`` plugin).
  91. #. CSS/JS/Images for the theme are put in the right places (the ``copy_assets`` and ``bundles`` plugins).
  92. #. A File describing the whole site is created (the ``sitemap`` plugin).
  93. You can add whatever you want to that list: just create a plugin for it.
  94. You can also expand Nikola's capabilities at several points:
  95. compilers
  96. Nikola supports a variety of markups. If you want to add another one, you need to create
  97. a ``Compiler`` plugin.
  98. templates
  99. Nikola's themes can use Jinja2 or Mako templates. If you prefer another template system,
  100. you have to create a ``TemplateSystem`` plugin.
  101. themes
  102. To change how the generated site looks, you can create custom themes.
  103. And of course, you can also replace or extend each of the existing plugins.
  104. Nikola Architecture
  105. ===================
  106. .. thumbnail:: https://getnikola.com/images/architecture.png