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

handbook.rst 119KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230
  1. .. title: The Nikola Handbook
  2. .. slug: handbook
  3. .. date: 2012-03-30 23:00:00 UTC-03:00
  4. .. link:
  5. .. description:
  6. .. tags:
  7. .. has_math: true
  8. .. author: The Nikola Team
  9. :Version: 8.2.3
  10. .. class:: alert alert-primary float-md-right
  11. .. contents::
  12. All You Need to Know
  13. --------------------
  14. After you have Nikola `installed <https://getnikola.com/getting-started.html>`_:
  15. Create an empty site (with a setup wizard):
  16. ``nikola init mysite``
  17. You can create a site with demo files in it with ``nikola init --demo mysite``
  18. The rest of these commands have to be executed inside the new ``mysite`` folder.
  19. Create a post:
  20. ``nikola new_post``
  21. Edit the post:
  22. The filename should be in the output of the previous command.
  23. You can also use ``nikola new_post -e`` to open an editor automatically.
  24. Build the site:
  25. ``nikola build``
  26. Start the test server and open a browser:
  27. ``nikola serve -b``
  28. That should get you going. If you want to know more, this manual will always be here
  29. for you.
  30. DON'T READ THIS MANUAL. IF YOU NEED TO READ IT I FAILED, JUST USE THE THING.
  31. On the other hand, if anything about Nikola is not as obvious as it should be, by all
  32. means tell me about it :-)
  33. What's Nikola and what can you do with it?
  34. ------------------------------------------
  35. Nikola is a static website and blog generator. The very short explanation is
  36. that it takes some texts you wrote, and uses them to create a folder full
  37. of HTML files. If you upload that folder to a server, you will have a
  38. rather full-featured website, done with little effort.
  39. Its original goal is to create blogs, but it supports most kind of sites, and
  40. can be used as a CMS, as long as what you present to the user is your own content
  41. instead of something the user generates.
  42. Nikola can do:
  43. * A blog (`example <https://ralsina.me>`__)
  44. * Your company's site
  45. * Your personal site
  46. * A software project's site (`example <https://getnikola.com>`__)
  47. * A book's site
  48. Since Nikola-based sites don't run any code on the server, there is no way to process
  49. user input in forms.
  50. Nikola can't do:
  51. * Twitter
  52. * Facebook
  53. * An Issue tracker
  54. * Anything with forms, really (except for `comments`_!)
  55. Keep in mind that "static" doesn't mean **boring**. You can have animations
  56. or whatever fancy CSS3/HTML5 thingie you like. It only means all that HTML is
  57. generated already before being uploaded. On the other hand, Nikola sites will
  58. tend to be content-heavy. What Nikola is good at is at putting what you write
  59. out there.
  60. Getting Help
  61. ------------
  62. .. class:: lead
  63. `Get help here! <https://getnikola.com/contact.html>`_
  64. TL;DR:
  65. * You can file bugs at `the issue tracker <https://github.com/getnikola/nikola/issues>`__
  66. * You can discuss Nikola at the `nikola-discuss google group <https://groups.google.com/group/nikola-discuss>`_
  67. * You can subscribe to `the Nikola Blog <https://getnikola.com/blog>`_
  68. * You can follow `Nikola on Twitter <https://twitter.com/GetNikola>`_
  69. Why Static?
  70. -----------
  71. Most "modern" websites are *dynamic* in the sense that the contents of the site
  72. live in a database, and are converted into presentation-ready HTML only when a
  73. user wants to see the page. That's great. However, it presents some minor issues
  74. that static site generators try to solve.
  75. In a static site, the whole site, every page, *everything*, is created before
  76. the first user even sees it and uploaded to the server as a simple folder full
  77. of HTML files (and images, CSS, etc).
  78. So, let's see some reasons for using static sites:
  79. Security
  80. Dynamic sites are prone to experience security issues. The solution for that
  81. is constant vigilance, keeping the software behind the site updated, and
  82. plain old good luck. The stack of software used to provide a static site,
  83. like those Nikola generates, is much smaller (Just a web server).
  84. A smaller software stack implies less security risk.
  85. Obsolescence
  86. If you create a site using (for example) WordPress, what happens when WordPress
  87. releases a new version? You have to update your WordPress. That is not optional,
  88. because of security and support issues. If I release a new version of Nikola, and
  89. you don't update, *nothing* happens. You can continue to use the version you
  90. have now forever, no problems.
  91. Also, in the longer term, the very foundations of dynamic sites shift. Can you
  92. still deploy a blog software based on Django 0.96? What happens when your
  93. host stops supporting the PHP version you rely on? And so on.
  94. You may say those are long term issues, or that they won't matter for years. Well,
  95. I believe things should work forever, or as close to it as we can make them.
  96. Nikola's static output and its input files will work as long as you can install
  97. Python 3.7 or newer under Linux, Windows, or macOS and can find a server
  98. that sends files over HTTP. That's probably 10 or 15 years at least.
  99. Also, static sites are easily handled by the Internet Archive.
  100. Cost and Performance
  101. On dynamic sites, every time a reader wants a page, a whole lot of database
  102. queries are made. Then a whole pile of code chews that data, and HTML is
  103. produced, which is sent to the user. All that requires CPU and memory.
  104. On a static site, the highly optimized HTTP server reads the file from disk
  105. (or, if it's a popular file, from disk cache), and sends it to the user. You could
  106. probably serve a bazillion (technical term) page views from a phone using
  107. static sites.
  108. Lock-in
  109. On server-side blog platforms, sometimes you can't export your own data, or
  110. it's in strange formats you can't use in other services. I have switched
  111. blogging platforms from Advogato to PyCs to two homebrew systems, to Nikola,
  112. and have never lost a file, a URL, or a comment. That's because I have *always*
  113. had my own data in a format of my choice.
  114. With Nikola, you own your files, and you can do anything with them.
  115. Components
  116. ----------
  117. Nikola provides the following features:
  118. * Blog support, including:
  119. * Indexes
  120. * RSS and Atom feeds
  121. * Tags and categories, with pages and feeds
  122. * Author pages and feeds (not generated if ``ENABLE_AUTHOR_PAGES`` is set to ``False`` or there is only one author)
  123. * Archives with custom granularity (yearly or monthly)
  124. * `Comments`_
  125. * Static pages (not part of the blog)
  126. * `Math`_ rendering (via MathJax)
  127. * Custom output paths for generated pages
  128. * Pretty URLs (without ``.html``) that don’t need web server support
  129. * Easy page template customization
  130. * Internationalization support (my own blog is English and Spanish)
  131. * Sitemap generation (for search engines)
  132. * Custom deployment (if it’s a command, you can use it)
  133. * GitHub Pages deployment
  134. * Themes, easy appearance customization
  135. * `Multiple input formats <#supported-input-formats>`_, including reStructuredText and Markdown
  136. * Easy-to-create image galleries
  137. * Image thumbnail generation
  138. * Support for displaying source code listings
  139. * Custom search
  140. * Asset (CSS/JS) bundling
  141. * gzip compression (for sending via your web server)
  142. * Open Graph, Twitter Cards
  143. * Hyphenation
  144. * Custom `post processing filters`_ (eg. for minifying files or better typography)
  145. Getting Started
  146. ---------------
  147. .. class:: lead
  148. To set Nikola up and create your first site, read the `Getting Started Guide <https://getnikola.com/getting-started.html>`_.
  149. Creating a Blog Post
  150. --------------------
  151. .. sidebar:: Magic Links
  152. You will want to do things like "link from one post to another" or "link to an image gallery",
  153. etc. Sure, you can just figure out the URLs for each thing and use that. Or you can use
  154. Nikola's special link URLs. Those are done using the syntax ``link://kind/name`` and
  155. a full list of the included ones is `here <link://slug/path-handlers>`__ (BTW, I linked
  156. to that using ``link://slug/path-handlers``).
  157. Note that magic links with spaces won’t work with some input formats (eg.
  158. reST), so you should use slugs there (eg. ``link://tag/some-tag`` instead of
  159. ``link://tag/Some Tag``)
  160. To create a new post, the easiest way is to run ``nikola new_post``. You will
  161. be asked for a title for your post, and it will tell you where the post's file
  162. is located.
  163. By default, that file will contain also some extra information about your post ("the metadata").
  164. It can be placed in a separate file by using the ``-2`` option, but it's generally
  165. easier to keep it in a single location.
  166. The contents of your post have to be written (by default) in `reStructuredText <https://docutils.sourceforge.io/>`__
  167. but you can use a lot of different markups using the ``-f`` option.
  168. Currently, Nikola supports reStructuredText, Markdown, Jupyter Notebooks, HTML as input,
  169. can also use Pandoc for conversion, and has support for BBCode, CreoleWiki, txt2tags, Textile
  170. and more via plugins — for more details, read the `input format documentation
  171. <#multiple-input-formats>`__.
  172. You can learn reStructuredText syntax with the `reST quickstart <https://getnikola.com/quickstart.html>`__.
  173. Please note that Nikola does not support encodings other than UTF-8. Make sure
  174. to convert your input files to that encoding to avoid issues. It will prevent
  175. bugs, and Nikola will write UTF-8 output anyway.
  176. You can control what markup compiler is used for each file extension with the ``COMPILERS``
  177. option. The default configuration expects them to be placed in ``posts`` but that can be
  178. changed (see below, the ``POSTS`` and ``PAGES`` options)
  179. This is how it works:
  180. .. code:: console
  181. $ nikola new_post
  182. Creating New Post
  183. -----------------
  184. Title: How to make money
  185. Scanning posts....done!
  186. INFO: new_post: Your post's text is at: posts/how-to-make-money.rst
  187. The content of that file is as follows:
  188. .. code:: restructuredtext
  189. .. title: How to make money
  190. .. slug: how-to-make-money
  191. .. date: 2012-09-15 19:52:05 UTC
  192. .. tags:
  193. .. link:
  194. .. description:
  195. .. type: text
  196. Write your post here.
  197. You can edit these files with your favorite text editor, and once you are happy
  198. with the contents, generate the pages using ``nikola build``.
  199. The post page is generated by default using the ``post.tmpl`` template, which you can use
  200. to customize the output. You can also customize paths and the template filename
  201. itself — see `How does Nikola decide where posts should go?`
  202. Metadata fields
  203. ~~~~~~~~~~~~~~~
  204. Nikola supports many metadata fields in posts. All of them are
  205. translatable and almost all are optional.
  206. Basic
  207. `````
  208. title
  209. Title of the post. Using HTML/math in titles is not supported/recommended.
  210. If not specified, the file name will be used.
  211. slug
  212. Slug of the post. Used as the last component of the page URL. We recommend
  213. and default to using a restricted character set (``a-z0-9-_``) because
  214. other symbols may cause issues in URLs. If not specified, the file name will be used.
  215. So, if the slug is "the-slug" the page generated would be "the-slug.html" or
  216. "the-slug/index.html" (if you have the pretty URLs option enabled)
  217. One special case is setting the slug to "index". This means the page generated
  218. would be "some_folder/index.html", which means it will be open for the URL
  219. that ends in "some_folder" or "some_folder/".
  220. This is useful in some cases, in others may cause conflicts with other pages
  221. Nikola generates (like blog indexes) and as a side effect it disables
  222. "pretty URLs" for this page. So use with care.
  223. date
  224. Date of the post, defaults to now. Multiple date formats are accepted.
  225. Adding a timezone is recommended. (required for posts)
  226. tags
  227. Comma-separated tags of the post.
  228. status
  229. Can be set to ``published`` (default), ``featured``, ``draft``, or ``private``.
  230. has_math
  231. If set to ``true`` or ``yes``, MathJax resp. KaTeX support is enabled
  232. for this post.
  233. category
  234. Like tags, except each post can have only one, and they usually have
  235. more descriptive names.
  236. guid
  237. String used as GUID in RSS feeds and as ID in Atom feeds instead of the
  238. permalink.
  239. link
  240. Link to original source for content. May be displayed by some themes.
  241. description
  242. Description of the post. Used in ``<meta>`` tags for SEO.
  243. type
  244. Type of the post. See `Post Types`_ for details. Whatever you set here
  245. (prepended with ``post-``) will become a CSS class of the ``<article>``
  246. element for this post. Defaults to ``text`` (resulting in a ``post-text``
  247. class)
  248. Extra
  249. `````
  250. author
  251. Author of the post, will be used in the RSS feed and possibly in the post
  252. display (theme-dependent)
  253. enclosure
  254. Add an enclosure to this post when it's used in RSS. See `more information about enclosures <https://en.wikipedia.org/wiki/RSS_enclosure>`__
  255. data
  256. Path to an external data file (JSON/YAML/TOML dictionary), relative to ``conf.py``.
  257. Its keys are available for templates as ``post.data('key')``.
  258. Translated posts can have different values for this field, and the correct one will be
  259. used.
  260. See `The Global Context and Data files`_ for more details. This is
  261. especially useful used in combination with `shortcodes`_.
  262. filters
  263. See the `Post Processing Filters`_ section.
  264. hidetitle
  265. Set "True" if you do not want to see the **page** title as a
  266. heading of the output html file (does not work for posts).
  267. hyphenate
  268. Set "True" if you want this document to be hyphenated even if you have
  269. hyphenation disabled by default.
  270. nocomments
  271. Set to "True" to disable comments.
  272. pretty_url
  273. Set to "False" to disable pretty URL for this page.
  274. previewimage
  275. Designate a preview or other representative image path relative to BASE_URL
  276. for use with Open Graph for posts. Adds the image when sharing on social
  277. media, feeds, and many other uses.
  278. .. code:: restructuredtext
  279. .. previewimage: /images/looks_great_on_facebook.png
  280. If a post has no `previewimage` it will try to use the `DEFAULT_PREVIEW_IMAGE`
  281. option from the configuration.
  282. The image can be of any size and dimension (services will crop and adapt)
  283. but should less than 1 MB and be larger than 300x300 (ideally 600x600).
  284. This image is displayed by ``bootblog4`` for featured posts (see `Featured
  285. Posts`_ for details).
  286. template
  287. Change the template used to render this page/post specific page. That
  288. template needs to either be part of the theme, or be placed in a
  289. ``templates/`` folder inside your site.
  290. .. code:: restructuredtext
  291. .. template: foobar.tmpl
  292. updated
  293. The last time this post was updated, defaults to the post’s ``date``
  294. metadata value. It is not displayed by default in most themes, including
  295. the defaults — you can use ``post.formatted_updated(date_format)`` (and
  296. perhaps check ``if post.updated != post.date``) in your post template to
  297. show it.
  298. To add these metadata fields to all new posts by default, you can set the
  299. variable ``ADDITIONAL_METADATA`` in your configuration. For example, you can
  300. add the author metadata to all new posts by default, by adding the following
  301. to your configuration:
  302. .. code:: python
  303. ADDITIONAL_METADATA = {
  304. 'author': 'John Doe'
  305. }
  306. url_type
  307. Change the URL_TYPE setting for the given page only. Useful for eg. error
  308. pages which cannot use relative URLs.
  309. .. code:: restructuredtext
  310. .. url_type: full_path
  311. Metadata formats
  312. ~~~~~~~~~~~~~~~~
  313. Metadata can be in different formats.
  314. Current Nikola versions experimentally supports other metadata formats that make it more compatible with
  315. other static site generators. The currently supported metadata formats are:
  316. * reST-style comments (``.. name: value`` — default format)
  317. * Two-file format (reST-style, YAML, TOML)
  318. * Jupyter Notebook metadata
  319. * YAML, between ``---`` (Jekyll, Hugo)
  320. * TOML, between ``+++`` (Hugo)
  321. * reST docinfo (Pelican)
  322. * Markdown metadata extension (Pelican)
  323. * HTML meta tags (Pelican)
  324. You can add arbitrary meta fields in any format.
  325. When you create new posts, by default the metadata will be created as reST style comments.
  326. If you prefer a different format, you can set the ``METADATA_FORMAT`` to one of these values:
  327. * ``"Nikola"``: reST comments, wrapped in a HTML comment if needed (default)
  328. * ``"YAML"``: YAML wrapped in "---"
  329. * ``"TOML"``: TOML wrapped in "+++"
  330. * ``"Pelican"``: Native markdown metadata or reST docinfo fields. Nikola style for other formats.
  331. reST-style comments
  332. ```````````````````
  333. The “traditional” and default meta field format is:
  334. .. code:: text
  335. .. name: value
  336. If you are not using reStructuredText, make sure the fields are in a HTML comment in output.
  337. Also, note that this format does not support any multi-line values. Try YAML or reST docinfo if you need those.
  338. Two-file format
  339. ```````````````
  340. Meta information can also be specified in separate ``.meta`` files. Those support reST-style metadata, with names and custom fields. They look like the beginning of our reST files:
  341. .. code:: text
  342. .. title: How to make money
  343. .. slug: how-to-make-money
  344. .. date: 2012-09-15 19:52:05 UTC
  345. You can also use YAML or TOML metadata inside those (with the appropriate markers).
  346. Jupyter Notebook metadata
  347. `````````````````````````
  348. Jupyter posts can store meta information inside ``.ipynb`` files by using the ``nikola`` key inside notebook metadata. It can be edited by using *Edit → Edit Notebook Metadata* in Jupyter. Note that values are currently only strings. Sample metadata (Jupyter-specific information omitted):
  349. .. code:: json
  350. {
  351. "nikola": {
  352. "title": "How to make money",
  353. "slug": "how-to-make-money",
  354. "date": "2012-09-15 19:52:05 UTC"
  355. }
  356. }
  357. YAML metadata
  358. `````````````
  359. YAML metadata should be wrapped by a ``---`` separator (three dashes) and in that case, the usual YAML syntax is used:
  360. .. code:: yaml
  361. ---
  362. title: How to make money
  363. slug: how-to-make-money
  364. date: 2012-09-15 19:52:05 UTC
  365. ---
  366. TOML metadata
  367. `````````````
  368. TOML metadata should be wrapped by a "+++" separator (three plus signs) and in that case, the usual TOML syntax is used:
  369. .. code:: yaml
  370. +++
  371. title = "How to make money"
  372. slug = "how-to-make-money"
  373. date = "2012-09-15 19:52:05 UTC"
  374. +++
  375. reST docinfo
  376. ````````````
  377. Nikola can extract metadata from reStructuredText docinfo fields and the document itself, too:
  378. .. code:: restructuredtext
  379. How to make money
  380. =================
  381. :slug: how-to-make-money
  382. :date: 2012-09-15 19:52:05 UTC
  383. To do this, you need ``USE_REST_DOCINFO_METADATA = True`` in your ``conf.py``,
  384. and Nikola will hide the docinfo fields in the output if you set
  385. ``HIDE_REST_DOCINFO = True``.
  386. .. note::
  387. Keys are converted to lowercase automatically.
  388. This setting also means that the first heading in a post will be removed
  389. and considered a title. This is important if you’re mixing metadata
  390. styles. This can be solved by putting a reST comment before your title.
  391. Pelican/Markdown metadata
  392. `````````````````````````
  393. Markdown Metadata (Pelican-style) only works in Markdown files, and requires the ``markdown.extensions.meta`` extension
  394. (see `MARKDOWN_EXTENSIONS <#markdown>`__). The exact format is described in
  395. the `markdown metadata extension docs. <https://python-markdown.github.io/extensions/meta_data/>`__
  396. .. code:: text
  397. title: How to make money
  398. slug: how-to-make-money
  399. date: 2012-09-15 19:52:05 UTC
  400. Note that keys are converted to lowercase automatically.
  401. HTML meta tags
  402. ``````````````
  403. For HTML source files, metadata will be extracted from ``meta`` tags, and the title from the ``title`` tag.
  404. Following Pelican's behaviour, tags can be put in a "tags" meta tag or in a "keywords" meta tag. Example:
  405. .. code:: html
  406. <html>
  407. <head>
  408. <title>My super title</title>
  409. <meta name="tags" content="thats, awesome" />
  410. <meta name="date" content="2012-07-09 22:28" />
  411. <meta name="modified" content="2012-07-10 20:14" />
  412. <meta name="category" content="yeah" />
  413. <meta name="authors" content="Conan Doyle" />
  414. <meta name="summary" content="Short version for index and feeds" />
  415. </head>
  416. <body>
  417. This is the content of my super blog post.
  418. </body>
  419. </html>
  420. Mapping metadata from other formats
  421. ```````````````````````````````````
  422. If you import posts from other engines, those may not work with Nikola out of the box due to differing names. However, you can create a mapping to convert meta field names from those formats into what Nikola expects.
  423. For Pelican, use:
  424. .. code:: python
  425. METADATA_MAPPING = {
  426. "rest_docinfo": {"summary": "description", "modified": "updated"},
  427. "markdown_metadata": {"summary": "description", "modified": "updated"}
  428. "html_metadata": {"summary": "description", "modified": "updated"}
  429. }
  430. For Hugo, use:
  431. .. code:: python
  432. METADATA_MAPPING = {
  433. "yaml": {"lastmod": "updated"},
  434. "toml": {"lastmod": "updated"}
  435. }
  436. The following source names are supported: ``yaml``, ``toml``, ``rest_docinfo``, ``markdown_metadata``.
  437. Additionally, you can use ``METADATA_VALUE_MAPPING`` to perform any extra conversions on metadata for **all** posts of a given format (``nikola`` metadata is also supported). A few examples:
  438. .. code:: python
  439. METADATA_VALUE_MAPPING = {
  440. "yaml": {"keywords": lambda value: ', '.join(value)}, # yaml: 'keywords' list -> str
  441. "nikola": {
  442. "widgets": lambda value: value.split(', '), # nikola: 'widgets' comma-separated string -> list
  443. "tags": str.lower # nikola: force lowercase 'tags' (input would be string)
  444. }
  445. }
  446. Multilingual posts
  447. ~~~~~~~~~~~~~~~~~~
  448. If you are writing a multilingual site, you can also create a per-language
  449. post file (for example: ``how-to-make-money.es.txt`` with the default TRANSLATIONS_PATTERN, see below).
  450. This one can replace metadata of the default language, for example:
  451. * The translated title for the post or page
  452. * A translated version of the page name
  453. The pattern used for finding translations is controlled by the
  454. TRANSLATIONS_PATTERN variable in your configuration file.
  455. The default is to put the language code before the file extension,
  456. so the German translation of ``some_file.rst`` should be named
  457. ``some_file.de.rst``. This is because the TRANSLATIONS_PATTERN variable is by
  458. default set to:
  459. .. code:: python
  460. TRANSLATIONS_PATTERN = "{path}.{lang}.{ext}"
  461. .. admonition:: Considered languages
  462. Nikola will only look for translation of input files for languages
  463. specified in the TRANSLATIONS variable.
  464. In case you translate your posts, you might also want to adjust various
  465. other settings so that the generated URLs match the translation. You can
  466. find most places in ``conf.py`` by searching for ``(translatable)``. For example,
  467. you might want to localize ``/categories/`` (search for ``TAG_PATH``), ``/pages/``
  468. and ``/posts/`` (search for ``POSTS`` and ``PAGES``, or see the next section), or
  469. how to adjust the URLs for subsequent pages for indexes (search for
  470. ``INDEXES_PRETTY_PAGE_URL``).
  471. Nikola supports multiple languages for a post (we have almost 50 translations!). If you wish to
  472. add support for more languages, check out `the Transifex page for Nikola <https://www.transifex.com/projects/p/nikola/>`_.
  473. How does Nikola decide where posts should go?
  474. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  475. The place where the post will be placed by ``new_post`` (the first one that
  476. matches the given format) and the final post destination (the first one that
  477. matches a given file) is based on the ``POSTS`` and ``PAGES`` configuration
  478. options. The exact mechanism is explained above the config options in the
  479. ``conf.py`` file, and also reproduced below:
  480. .. code:: python
  481. # POSTS and PAGES contains (wildcard, destination, template) tuples.
  482. #
  483. # The wildcard is used to generate a list of post source files
  484. # (whatever/thing.rst, for example).
  485. #
  486. # That fragment could have an associated metadata file (whatever/thing.meta),
  487. # and optionally translated files (example for Spanish, with code "es"):
  488. # whatever/thing.es.rst and whatever/thing.es.meta
  489. #
  490. # This assumes you use the default TRANSLATIONS_PATTERN.
  491. #
  492. # From those files, a set of HTML fragment files will be generated:
  493. # cache/whatever/thing.html (and maybe cache/whatever/thing.html.es)
  494. #
  495. # These files are combined with the template to produce rendered
  496. # pages, which will be placed at
  497. # output/TRANSLATIONS[lang]/destination/pagename.html
  498. #
  499. # where "pagename" is the "slug" specified in the metadata file.
  500. # The page might also be placed in /destination/pagename/index.html
  501. # if PRETTY_URLS are enabled.
  502. #
  503. # The difference between POSTS and PAGES is that POSTS are added
  504. # to feeds, indexes, tag lists and archives and are considered part
  505. # of a blog, while PAGES are just independent HTML pages.
  506. #
  507. # Finally, note that destination can be translated, i.e. you can
  508. # specify a different translation folder per language. Example:
  509. # PAGES = (
  510. # ("pages/*.rst", {"en": "pages", "de": "seiten"}, "page.tmpl"),
  511. # ("pages/*.md", {"en": "pages", "de": "seiten"}, "page.tmpl"),
  512. # )
  513. POSTS = (
  514. ("posts/*.rst", "posts", "post.tmpl"),
  515. ("posts/*.txt", "posts", "post.tmpl"),
  516. ("posts/*.html", "posts", "post.tmpl"),
  517. )
  518. PAGES = (
  519. ("pages/*.rst", "pages", "page.tmpl"),
  520. ("pages/*.txt", "pages", "page.tmpl"),
  521. ("pages/*.html", "pages", "page.tmpl"),
  522. )
  523. .. admonition:: POSTS and PAGES are not flat!
  524. Even if the syntax may suggest you can't, you can create any directory structure you want
  525. inside ``posts/`` or ``pages/`` and it will be reflected in the output. For example,
  526. ``posts/foo/bar.txt`` would produce ``output/posts/foo/bar.html``, assuming the slug is also ``bar``.
  527. If you have ``PRETTY_URLS`` enabled, that would be ``output/posts/foo/bar/index.html``.
  528. .. warning::
  529. Removing the ``.rst`` entries is not recommended. Some features (eg.
  530. shortcodes) may not work properly if you do that.
  531. The ``new_post`` command
  532. ~~~~~~~~~~~~~~~~~~~~~~~~
  533. ``new_post`` will use the *first* path in ``POSTS`` (or ``PAGES`` if ``-p`` is
  534. supplied) that ends with the extension of your desired markup format (as
  535. defined in ``COMPILERS`` in ``conf.py``) as the directory that the new post will be
  536. written into. If no such entry can be found, the post won’t be created.
  537. The ``new_post`` command supports some options:
  538. .. code:: text
  539. $ nikola help new_post
  540. Purpose: create a new blog post or site page
  541. Usage: nikola new_post [options] [path]
  542. Options:
  543. -p, --page Create a page instead of a blog post. (see also: `nikola new_page`)
  544. -t ARG, --title=ARG Title for the post.
  545. -a ARG, --author=ARG Author of the post.
  546. --tags=ARG Comma-separated tags for the post.
  547. -1 Create the post with embedded metadata (single file format)
  548. -2 Create the post with separate metadata (two file format)
  549. -e Open the post (and meta file, if any) in $EDITOR after creation.
  550. -f ARG, --format=ARG Markup format for the post (use --available-formats for list)
  551. -F, --available-formats List all available input formats
  552. -s Schedule the post based on recurrence rule
  553. -i ARG, --import=ARG Import an existing file instead of creating a placeholder
  554. -d, --date-path Create post with date path (eg. year/month/day, see NEW_POST_DATE_PATH_FORMAT in config)
  555. The optional ``path`` parameter tells Nikola exactly where to put it instead of guessing from your config.
  556. So, if you do ``nikola new_post posts/random/foo.txt`` you will have a post in that path, with
  557. "foo" as its slug. You can also provide a directory name, in which case Nikola
  558. will append the file name for you (generated from title).
  559. The ``-d, --date-path`` option automates creation of ``year/month/day`` or
  560. similar directory structures. It can be enabled on a per-post basis, or you can
  561. use it for every post if you set ``NEW_POST_DATE_PATH = True`` in conf.py.
  562. .. code:: python
  563. # Use date-based path when creating posts?
  564. # Can be enabled on a per-post basis with `nikola new_post -d`.
  565. # NEW_POST_DATE_PATH = False
  566. # What format to use when creating posts with date paths?
  567. # Default is '%Y/%m/%d', other possibilities include '%Y' or '%Y/%m'.
  568. # NEW_POST_DATE_PATH_FORMAT = '%Y/%m/%d'
  569. Teasers
  570. ~~~~~~~
  571. You may not want to show the complete content of your posts either on your
  572. index page or in RSS feeds, but to display instead only the beginning of them.
  573. If it's the case, you only need to add a "magical comment" ``TEASER_END`` or
  574. ``END_TEASER`` in your post.
  575. In reStructuredText:
  576. .. code:: restructuredtext
  577. .. TEASER_END
  578. In Markdown (or basically, the resulting HTML of any format):
  579. .. code:: html
  580. <!-- TEASER_END -->
  581. By default all your RSS feeds will be shortened (they'll contain only teasers)
  582. whereas your index page will still show complete posts. You can change
  583. this behavior with your ``conf.py``: ``INDEX_TEASERS`` defines whether index
  584. page should display the whole contents or only teasers. ``FEED_TEASERS``
  585. works the same way for your Atom and RSS feeds.
  586. By default, teasers will include a "read more" link at the end. If you want to
  587. change that text, you can use a custom teaser:
  588. .. code:: restructuredtext
  589. .. TEASER_END: click to read the rest of the article
  590. You can override the default value for ``TEASER_END`` in ``conf.py`` — for
  591. example, the following example will work for ``.. more``, and will be
  592. compatible with both WordPress and Nikola posts:
  593. .. code:: python
  594. import re
  595. TEASER_REGEXP = re.compile('<!--\s*(more|TEASER_END|END_TEASER)(:(.+))?\s*-->', re.IGNORECASE)
  596. Or you can completely customize the link using the ``READ_MORE_LINK`` option.
  597. .. code:: python
  598. # A HTML fragment with the Read more... link.
  599. # The following tags exist and are replaced for you:
  600. # {link} A link to the full post page.
  601. # {read_more} The string “Read more” in the current language.
  602. # {{ A literal { (U+007B LEFT CURLY BRACKET)
  603. # }} A literal } (U+007D RIGHT CURLY BRACKET)
  604. # READ_MORE_LINK = '<p class="more"><a href="{link}">{read_more}…</a></p>'
  605. Drafts
  606. ~~~~~~
  607. If you set the ``status`` metadata field of a post to ``draft``, it will not be shown
  608. in indexes and feeds. It *will* be compiled, and if you deploy it it *will* be made
  609. available, so use with care. If you wish your drafts to be not available in your
  610. deployed site, you can set ``DEPLOY_DRAFTS = False`` in your configuration. This will
  611. not work if you include ``nikola build`` in your ``DEPLOY_COMMANDS``, as the
  612. option removes the draft posts before any ``DEPLOY_COMMANDS`` are run.
  613. Also if a post has a date in the future, it will not be shown in indexes until
  614. you rebuild after that date. This behavior can be disabled by setting
  615. ``FUTURE_IS_NOW = True`` in your configuration, which will make future posts be
  616. published immediately. Posts dated in the future are *not* deployed by default
  617. (when ``FUTURE_IS_NOW = False``). To make future posts available in the
  618. deployed site, you can set ``DEPLOY_FUTURE = True`` in your configuration.
  619. Generally, you want FUTURE_IS_NOW and DEPLOY_FUTURE to be the same value.
  620. Private Posts
  621. ~~~~~~~~~~~~~
  622. If you set the ``status`` metadata field of a post to ``private``, it will not be shown
  623. in indexes and feeds. It *will* be compiled, and if you deploy it it *will* be made
  624. available, so it will not generate 404s for people who had linked to it.
  625. Featured Posts
  626. ~~~~~~~~~~~~~~
  627. Some themes, ``bootblog4`` in particular, support featured posts. To mark a
  628. post as featured, simply set the ``status`` meta field to ``featured``. All
  629. featured posts are available in index templates in a ``featured``
  630. list, but only if this is the main blog index.
  631. For bootblog4, you can display up to three posts as featured: one can be shown
  632. in a large gray box (jumbotron), and two more can appear in small white
  633. cards. In order to enable this feature, you need to add ``THEME_CONFIG`` to
  634. your configuration, and set it up properly:
  635. .. code:: python
  636. THEME_CONFIG = {
  637. DEFAULT_LANG: {
  638. # Show the latest featured post in a large box, with the previewimage as its background.
  639. 'featured_large': True,
  640. # Show the first (remaining) two featured posts in small boxes.
  641. 'featured_small': True,
  642. # Show featured posts on mobile.
  643. 'featured_on_mobile': True,
  644. # Show image in `featured_large` on mobile.
  645. # `featured_small` displays them only on desktop.
  646. 'featured_large_image_on_mobile': False,
  647. # Strip HTML from featured post text.
  648. 'featured_strip_html': True,
  649. # Contents of the sidebar, If empty, the sidebar is not displayed.
  650. 'sidebar': ''
  651. }
  652. }
  653. You can pick betweeen (up to) 1, 2, or 3 featured posts. You can mix
  654. ``featured_large`` and ``featured_small``, rest assured that Nikola will always
  655. display the latest posts no matter what setup you choose. If only one posts
  656. qualifies for the small cards, one card taking up all the width will appear.
  657. Both featured box formats display an image to the right. You can set it by changing the ``previewimage`` meta value to the full path to the image (eg. ``.. previewimage: /images/featured1.png``). This works best with images in portrait orientation.
  658. Note that, due to space constraints, only the large box may show the image on
  659. mobile, below the text (this behavior can be disbled). Small boxes never
  660. display images on mobile. In particular: ``xs`` and ``sm`` display only the
  661. large image, and only if configured; ``md`` displays only the large image,
  662. ``lg`` displays all three images.
  663. The boxes display only the teaser. We recommend keeping it short so
  664. you don’t get an ugly scrollbar.
  665. Finally, here’s an example (you’ll need to imagine a scrollbar in the right box
  666. yourself):
  667. .. thumbnail:: https://getnikola.com/images/bootblog4-featured2x.png
  668. :align: center
  669. :alt: An example of how featured posts look in bootblog4.
  670. Queuing Posts
  671. ~~~~~~~~~~~~~
  672. Some blogs tend to have new posts based on a schedule (for example,
  673. every Mon, Wed, Fri) but the blog authors don't like to manually
  674. schedule their posts. You can schedule your blog posts based on a
  675. rule, by specifying a rule in the ``SCHEDULE_RULE`` in your
  676. configuration. You can either post specific blog posts according to
  677. this schedule by using the ``--schedule`` flag on the ``new_post``
  678. command or post all new posts according to this schedule by setting
  679. ``SCHEDULE_ALL = True`` in your configuration. (Note: This feature
  680. requires that the ``FUTURE_IS_NOW`` setting is set to ``False``)
  681. For example, if you would like to schedule your posts to be on every
  682. Monday, Wednesday and Friday at 7am, add the following
  683. ``SCHEDULE_RULE`` to your configuration:
  684. .. code:: python
  685. SCHEDULE_RULE = 'RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;BYHOUR=7;BYMINUTE=0;BYSECOND=0'
  686. For more details on how to specify a recurrence rule, look at the
  687. `iCal specification <https://www.kanzaki.com/docs/ical/rrule.html>`_.
  688. Or if you are scared of this format, many calendaring applications (eg. Google
  689. Calendar) offer iCal exports, so you can copy-paste the repeat rule from a
  690. generated iCal (``.ics``) file (which is a human-readable text file).
  691. Say, you get a free Sunday, and want to write a flurry of new posts,
  692. or at least posts for the rest of the week, you would run the
  693. ``new_post`` command with the ``--schedule`` flag, as many times as
  694. you want:
  695. .. code:: console
  696. $ nikola new_post --schedule
  697. # Creates a new post to be posted on Monday, 7am.
  698. $ nikola new_post -s
  699. # Creates a new post to be posted on Wednesday, 7am.
  700. $ nikola new_post -s
  701. # Creates a new post to be posted on Friday, 7am.
  702. .
  703. .
  704. .
  705. All these posts get queued up according to your schedule, but note
  706. that you will anyway need to build and deploy your site for the posts
  707. to appear online. You can have a cron job that does this regularly.
  708. Post Types
  709. ~~~~~~~~~~
  710. Nikola supports specifying post types, just like Tumblr does. Post
  711. types affect the look of your posts, by adding a ``post-YOURINPUTHERE``
  712. CSS class to the post. Each post can have one and exactly one type. Nikola
  713. styles the following types in the default themes:
  714. .. class:: table table-bordered
  715. +-----------------+----------------------------+------------------+
  716. | Name(s) | Description | Styling |
  717. +=================+============================+==================+
  718. | text | plain text — default value | standard |
  719. +-----------------+----------------------------+------------------+
  720. | micro | “small” (short) posts | big serif font |
  721. +-----------------+----------------------------+------------------+
  722. Indexes
  723. ~~~~~~~
  724. All your posts that are not drafts, private or dated in the future, will be
  725. shown in indexes.
  726. Settings
  727. ````````
  728. Indexes are put in the ``INDEX_PATH`` directory, which defaults to an empty
  729. string (site root). The “main” index is ``index.html``, and all the further
  730. indexes are ``index-*.html``, respectively.
  731. By default, 10 posts are displayed on an index page. This can be changed with
  732. ``INDEX_DISPLAY_POST_COUNT``. Indexes can show full posts or just the teasers,
  733. as controlled by the ``INDEX_TEASERS`` setting (defaults to ``False``).
  734. Titles of the pages can be controlled by using ``INDEXES_TITLES``,
  735. ``INDEXES_PAGES`` and ``INDEXES_PAGES_MAIN`` settings.
  736. Categories and tags use simple lists by default that show only titles and
  737. dates; however, you can switch them to full indexes by using
  738. ``CATEGORY_PAGES_ARE_INDEXES`` and ``TAG_PAGES_ARE_INDEXES``, respectively.
  739. Something similar happens with authors. To use full indexes in authors, set
  740. ``AUTHOR_PAGES_ARE_INDEXES`` to ``True``.
  741. Static indexes
  742. ``````````````
  743. Nikola uses *static indexes* by default. This means that ``index-1.html`` has
  744. the oldest posts, and the newest posts past the first 10 are in
  745. ``index-N.html``, where ``N`` is the highest number. Only the page with the
  746. highest number and the main page (``index-N.html`` and ``index.html``) are
  747. rebuilt (the others remain unchanged). The page that appears when you click
  748. *Older posts* on the index page, ``index-N.html``, might contain **less than 10
  749. posts** if there are not enough posts to fill up all pages.
  750. This can be disabled by setting ``INDEXES_STATIC`` to ``False``. In that mode,
  751. ``index-1.html`` contains all the newest posts past the first 10 and will
  752. always contain 10 posts (unless you have less than 20). The last page,
  753. ``index-N.html``, contains the oldest posts, and might contain less than 10
  754. posts. This is how many blog engines and CMSes behave. Note that this will
  755. lead to rebuilding all index pages, which might be a problem for larger blogs
  756. (with a lot of index pages).
  757. Post taxonomy
  758. ~~~~~~~~~~~~~
  759. There are two taxonomy systems in Nikola, or two ways to organize posts. Those are tags and categories. They are visible on the *Tags and Categories* page, by default available at ``/categories/``. Each tag/category has an index page and feeds.
  760. Tags
  761. ````
  762. Tags are the smallest and most basic of the taxonomy items. A post can have multiple tags, specified using the ``tags`` metadata entry (comma-separated). You should provide many tags to help your readers, and perhaps search engines, find content on your site.
  763. Please note that tags are case-sensitive and that you cannot have two tags that differ only in case/punctuation (eg. using ``nikola`` in one post and ``Nikola`` in another will lead to a crash):
  764. .. code:: text
  765. ERROR: Nikola: You have tags that are too similar: Nikola and nikola
  766. ERROR: Nikola: Tag Nikola is used in: posts/second-post.rst
  767. ERROR: Nikola: Tag nikola is used in: posts/1.rst
  768. You can also generate a tag cloud with the `tx3_tag_cloud <https://plugins.getnikola.com/v7/tx3_tag_cloud/>`_ plugin or get a data file for a tag cloud with the `tagcloud <https://plugins.getnikola.com/v8/tagcloud/>`_ plugin.
  769. Categories
  770. ``````````
  771. The next unit for organizing your content are categories. A post can have only one category, specified with the ``category`` meta tag. They are displayed alongside tags. You can have categories and tags with the same name (categories’ RSS and HTML files are prefixed with ``cat_`` by default).
  772. Categories are handy to organize different parts of your blog, parts that are about different topics. Unlike tags, which you should have tens (hundreds?) of, the list of categories should be shorter.
  773. Nikola v7 used to support a third taxonomy, called sections. Those have been removed, but all the functionality can be recreated by using the ``CATEGORY_DESTPATH`` settings.
  774. Configuring tags and categories
  775. ```````````````````````````````
  776. There are multiple configuration variables dedicated to each of the two taxonomies. You can set:
  777. * ``TAG_PATH``, ``TAGS_INDEX_PATH``, ``CATEGORY_PATH``, ``CATEGORY_PREFIX`` to configure paths used for tags and categories
  778. * ``TAG_TITLES``, ``CATEGORY_TITLES`` to set titles and descriptions for index pages
  779. * ``TAG_DESCRIPTIONS``, ``CATEGORY_DESCRIPTIONS`` to set descriptions for each of the items
  780. * ``CATEGORY_ALLOW_HIERARCHIES`` and ``CATEGORY_OUTPUT_FLAT_HIERARCHIES`` to allow hierarchical categories
  781. * ``TAG_PAGES_ARE_INDEXES`` and ``CATEGORY_PAGES_ARE_INDEXES`` to display full-size indexes instead of simple post lists
  782. * ``HIDDEN_TAGS``. ``HIDDEN_CATEGORIES`` to make some tags/categories invisible in lists
  783. * ``CATEGORY_DESTPATH_AS_DEFAULT`` to use the destination path as the category if none is specified in the post
  784. * ``CATEGORY_DESTPATH_TRIM_PREFIX`` to trim the prefix that comes from ``POSTS`` for the destination path
  785. * ``CATEGORY_DESTPATH_FIRST_DIRECTORY`` to only use the first directory name for the defaulted category
  786. * ``CATEGORY_DESTPATH_NAMES`` to specify friendly names for defaulted categories
  787. * ``CATEGORY_PAGES_FOLLOW_DESTPATH`` to put category pages next to their related posts (via destpath)
  788. What if I don’t want a blog?
  789. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  790. If you want a static site that does not have any blog-related elements, see our
  791. `Creating a Site (Not a Blog) with Nikola`__ guide.
  792. __ https://getnikola.com/creating-a-site-not-a-blog-with-nikola.html
  793. Creating a Page
  794. ---------------
  795. Pages are the same as posts, except that:
  796. * They are not added to the front page
  797. * They don't appear on the RSS feed
  798. * They use the ``page.tmpl`` template instead of ``post.tmpl`` by default
  799. The default configuration expects the page's metadata and text files to be on the
  800. ``pages`` folder, but that can be changed (see ``PAGES`` option above).
  801. You can create the page's files manually or use the ``new_post`` command
  802. with the ``-p`` option, which will place the files in the folder that
  803. has ``use_in_feed`` set to False.
  804. In some places (including default directories and templates), pages are called
  805. *stories* for historic reasons. Both are synonyms for the same thing: pages
  806. that are not blog posts.
  807. Supported input formats
  808. -----------------------
  809. Nikola supports multiple input formats. Out of the box, we have compilers available for:
  810. * reStructuredText (default and pre-configured)
  811. * `Markdown`_ (pre-configured since v7.8.7)
  812. * `Jupyter Notebook`_
  813. * `HTML`_
  814. * `PHP`_
  815. * anything `Pandoc`_ supports (including Textile, DocBook, LaTeX, MediaWiki,
  816. TWiki, OPML, Emacs Org-Mode, txt2tags, Microsoft Word .docx, EPUB, Haddock markup)
  817. Plus, we have specialized compilers in the Plugins Index for:
  818. * `AsciiDoc <https://plugins.getnikola.com/#asciidoc>`_
  819. * `BBCode <https://plugins.getnikola.com/#bbcode>`_
  820. * `CommonMark <https://plugins.getnikola.com/#commonmark>`_
  821. * `IRC logs <https://plugins.getnikola.com/#irclogs>`_
  822. * `Markmin <https://plugins.getnikola.com/#markmin>`_
  823. * `MediaWiki (smc.mw) <https://plugins.getnikola.com/#mediawiki>`_
  824. * `Misaka <https://plugins.getnikola.com/#misaka>`_
  825. * `ODT <https://plugins.getnikola.com/#odt>`_
  826. * `Emacs Org-Mode <https://plugins.getnikola.com/#orgmode>`_
  827. * `reST with HTML 5 output <https://plugins.getnikola.com/#rest_html5>`_
  828. * `Textile <https://plugins.getnikola.com/#textile>`_
  829. * `txt2tags <https://plugins.getnikola.com/#txt2tags>`_
  830. * `CreoleWiki <https://plugins.getnikola.com/#wiki>`_
  831. * `WordPress posts <https://plugins.getnikola.com/#wordpress_compiler>`_
  832. To write posts in a different format, you need to configure the compiler and
  833. paths. To create a post, use ``nikola new_post -f COMPILER_NAME``, eg. ``nikola
  834. new_post -f markdown``. The default compiler used is the first entry in POSTS
  835. or PAGES.
  836. Configuring other input formats
  837. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  838. In order to use input formats other than reStructuredText, you need some extra
  839. setup.
  840. 1. Make sure you have the compiler for the input format you want. Some
  841. input formats are supported out-of-the-box, but others must be installed from
  842. the Plugins repository. You may also need some extra dependencies. You
  843. will get helpful errors if you try to build when missing something.
  844. 2. You must ensure the compiler and your desired input file extension is included
  845. in the ``COMPILERS`` dict and does not conflict with any other format. This
  846. is extremely important for the pandoc compiler.
  847. 3. Finally, you must configure the ``POSTS`` and ``PAGES`` tuples. Follow the
  848. instructions and the format set by pre-existing entries. Make sure to use
  849. the same extension as is set in ``COMPILERS`` and configure the outputs
  850. properly.
  851. Markdown
  852. ````````
  853. To use Markdown in your posts/pages, make sure ``markdown`` is in your
  854. ``COMPILERS`` and that at least one of your desired extensions is defined in
  855. ``POSTS`` and ``PAGES``.
  856. You can use Python-Markdown extensions by setting the ``MARKDOWN_EXTENSIONS``
  857. config option:
  858. .. code:: python
  859. MARKDOWN_EXTENSIONS = ['fenced_code', 'codehilite', 'extra']
  860. Nikola comes with some Markdown Extensions built-in and enabled by default,
  861. namely a gist directive, a podcast directive, and ``~~strikethrough~~`` support.
  862. Jupyter Notebook
  863. ````````````````
  864. To use Jupyter Notebooks as posts/pages, make sure ``ipynb`` is in your
  865. ``COMPILERS`` and that the ``.ipynb`` extension is defined in ``POSTS`` and
  866. ``PAGES``.
  867. The ``-f`` argument to ``new_post`` should be used in the ``ipynb@KERNEL`` format.
  868. It defaults to Python in the version used by Nikola if not specified.
  869. Jupyter Notebooks are also supported in stand-alone listings, if Jupyter
  870. support is enabled site-wide. You must have something for ``.ipynb`` in POSTS
  871. or PAGES for the feature to work.
  872. HTML
  873. ````
  874. To use plain HTML in your posts/pages, make sure ``html`` is in your
  875. ``COMPILERS``
  876. and that the ``.html`` extension is defined in ``POSTS`` and ``PAGES``.
  877. PHP
  878. ```
  879. There are two ways of using PHP within Nikola:
  880. 1. To use PHP in your posts/pages (inside your site, with the theme and
  881. everything), make sure ``php`` is in your ``COMPILERS`` and that the ``.php``
  882. extension is defined in ``POSTS`` and ``PAGES``.
  883. 2. To use PHP as standalone files (without any modifications), put them in
  884. ``files/`` (or whatever ``FILES_FOLDERS`` is configured to).
  885. Pandoc
  886. ``````
  887. To use Pandoc, you must uncomment the entry in ``COMPILERS`` and set the
  888. extensions list to your desired extensions while also removing them from their
  889. original compilers. The input format is inferred from the extension by Pandoc.
  890. Using Pandoc for reStructuredText, Markdown and other input formats that have a
  891. standalone Nikola plugin is **not recommended** as it disables plugins and
  892. extensions that are usually provided by Nikola.
  893. Shortcodes
  894. ----------
  895. This feature is "inspired" (copied wholesale) from `Hugo <https://gohugo.io/extras/shortcodes/>`__ so I will
  896. steal part of their docs too.
  897. A shortcode is a simple snippet inside a content file that Nikola will render using a predefined template or
  898. custom code from a plugin.
  899. To use them from plugins, please see `Extending Nikola <https://getnikola.com/extending.html#shortcodes>`__
  900. Using a shortcode
  901. ~~~~~~~~~~~~~~~~~
  902. In your content files, a shortcode can be called by using this form:
  903. .. code:: text
  904. {{% raw %}}{{% name parameters %}}{{% /raw %}}
  905. Shortcode parameters are space delimited. Parameters with spaces can be quoted (or backslash escaped).
  906. The first word is always the name of the shortcode. Parameters follow the name. Depending upon how the shortcode is defined, the parameters may be named, positional or both. The format for named parameters models that of HTML with the format name="value".
  907. Some shortcodes use or require closing shortcodes. Like HTML, the opening and closing shortcodes match (name only), the closing being prepended with a slash.
  908. Example of a paired shortcode (note that we don't have a highlight shortcode yet ;-):
  909. .. code:: text
  910. {{% raw %}}{{% highlight python %}} A bunch of code here {{% /highlight %}}{{% /raw %}}
  911. .. admonition:: Shortcodes and reStructuredText
  912. In reStructuredText shortcodes may fail because docutils turns URL into links and everything breaks.
  913. For some shortcodes there are alternative docutils directives (example, you can use the media
  914. **directive** instead of the media shortcode.
  915. Also, you can use the shortcode **role**:
  916. .. code:: text
  917. :sc:`{{% raw %}}{{% shortcode here %}}{{% /raw %}}`
  918. That role passes text unaltered, so shortcodes behave correctly.
  919. Built-in shortcodes
  920. ~~~~~~~~~~~~~~~~~~~
  921. .. warning::
  922. Some of the shortcodes are implemented as bindings to reST directives. In
  923. order to use them, you need at least one entry for ``*.rst`` in
  924. POSTS/PAGES.
  925. chart
  926. Create charts via PyGal. This is similar to the `chart directive <#chart>`__ except the syntax is adapted to
  927. shortcodes. This is an example:
  928. .. code:: text
  929. {{% raw %}}{{% chart Bar title='Browser usage evolution (in %)'
  930. x_labels='["2002","2003","2004","2005","2006","2007"]' %}}
  931. 'Firefox', [None, None, 0, 16.6, 25, 31]
  932. 'Chrome', [None, None, None, None, None, None]
  933. 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
  934. 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
  935. {{% /chart %}}{{% /raw %}}
  936. Additionally, you can use a file_data argument which can point to a JSON or YAML file, and will be used for both arguments and data.
  937. Example:
  938. .. code:: json
  939. {
  940. "x_labels": ["2002","2003","2004","2005","2006","2007"],
  941. "data": {
  942. "Firefox": [null, null, 0, 16.6, 25, 31],
  943. "Chrome": [null, null, null, null, null, null],
  944. "IE": [85.8, 84.6, 84.7, 74.5, 66, 58.6],
  945. "Others": [14.2, 15.4, 15.3, 8.9, 9, 10.4]
  946. }
  947. }
  948. Which can be used like this:
  949. .. code:: text
  950. {{% raw %}}{{% chart Bar title='Browser usage evolution (in %)' data_file="posts/browsers.json" %}}
  951. {{% /chart %}}
  952. {{% /raw %}}
  953. If the data or any option is available in both the ``data_file`` and the document, the document has priority.
  954. doc
  955. Will link to a document in the page, see `Doc role for details
  956. <#doc>`__. Example:
  957. .. code:: restructuredtext
  958. {{% raw %}}Take a look at {{% doc %}}my other post <creating-a-theme>{{% /doc %}} about theme creating.{{% /raw %}}
  959. emoji
  960. Insert an emoji. For example:
  961. .. code:: text
  962. {{% raw %}}{{% emoji crying_face %}}{{% /raw %}}
  963. This generates a ``span`` with ``emoji`` CSS class, so you can style it with a nice font if you want.
  964. gist
  965. Show GitHub gists. If you know the gist's ID, this will show it in your site:
  966. .. code:: text
  967. {{% raw %}}{{% gist 2395294 %}} {{% /raw %}}
  968. listing
  969. Used to show a code listing. Example:
  970. .. code:: text
  971. {{% raw %}}{{% listing hello.py python linenumbers=True %}}{{% /raw %}}
  972. It takes a file name or path, an optional language to highlight, and a linenumbers option to enable/disable line numbers in the output.
  973. media
  974. Display media embedded from a URL, for example, this will embed a youtube video:
  975. .. code:: text
  976. {{% raw %}}{{% media url=https://www.youtube.com/watch?v=Nck6BZga7TQ %}}{{% /raw %}}
  977. Note that the shortcode won’t work if your compiler turns URLs into clickable links.
  978. post-list
  979. Will show a list of posts, see the `Post List directive for details <#post-list>`__.
  980. raw
  981. Passes the content along, mostly used so I can write this damn section and you can see the shortcodes instead
  982. of them being munged into shortcode **output**. I can't show an example because Inception.
  983. thumbnail
  984. Display image thumbnails, with optional captions. Examples:
  985. .. code:: text
  986. {{% raw %}}{{% thumbnail "/images/foo.png" %}}{{% /thumbnail %}}{{% /raw %}}
  987. {{% raw %}}{{% thumbnail "/images/foo.png" alt="Foo Image" align="center" %}}{{% /thumbnail %}}{{% /raw %}}
  988. {{% raw %}}{{% thumbnail "/images/foo.png" imgclass="image-grayscale" figclass="figure-shadow" %}}&lt;p&gt;Image caption&lt;/p&gt;{{% /thumbnail %}}{{% /raw %}}
  989. {{% raw %}}{{% thumbnail "/images/foo.png" alt="Foo Image" title="Insert title-text joke here" align="right" %}}&lt;p class="caption"&gt;Foo Image (right-aligned) caption&lt;/p&gt;{{% /thumbnail %}}{{% /raw %}}
  990. The following keyword arguments are supported:
  991. * alt (alt text for image)
  992. * align (image alignment, left/center/right)
  993. * linktitle (title text for the link, shown by e.g. baguetteBox)
  994. * title (title text for image)
  995. * imgclass (class for image)
  996. * figclass (class for figure, used only if you provide a caption)
  997. Looks similar to the reST thumbnail directive. Caption should be a HTML fragment.
  998. Community shortcodes
  999. ~~~~~~~~~~~~~~~~~~~~
  1000. Shortcodes created by the community are available in `the shortcodes repository on GitHub <https://github.com/getnikola/shortcodes>`_.
  1001. Template-based shortcodes
  1002. ~~~~~~~~~~~~~~~~~~~~~~~~~
  1003. If you put a template in ``shortcodes/`` called ``mycode.tmpl`` then Nikola
  1004. will create a shortcode called ``mycode`` you can use. Any options you pass to
  1005. the shortcode will be available as variables for that template. Non-keyword
  1006. options will be passed in a tuple variable named ``_args``.
  1007. The post in which the shortcode is being used is available as the ``post``
  1008. variable, so you can access the title as ``post.title``, and data loaded
  1009. via the ``data`` field in the metadata using ``post.data(key)``.
  1010. If you use the shortcode as paired, then the contents between the paired tags
  1011. will be available in the ``data`` variable. If you want to access the Nikola
  1012. object, it will be available as ``site``. Use with care :-)
  1013. .. note:: Template-based shortcodes use the same template engine as your site’s theme.
  1014. See :doc:`extending` for detailed information.
  1015. For example, if your ``shortcodes/foo.tmpl`` contains this:
  1016. .. code:: text
  1017. This uses the bar variable: ${bar}
  1018. And your post contains this:
  1019. .. code:: text
  1020. {{% raw %}}{{% foo bar=bla %}}{{% /raw %}}
  1021. Then the output file will contain:
  1022. .. code:: text
  1023. This uses the bar variable: bla
  1024. Finally, you can use a template shortcode without a file, by inserting the
  1025. template in the shortcode itself:
  1026. .. code:: html+mako
  1027. {{% raw %}}{{% template %}}{{% /raw %}}
  1028. <ul>
  1029. % for foo in bar:
  1030. <li>${foo}</li>
  1031. % endfor
  1032. </ul>
  1033. {{% raw %}}{{% /template %}}{{% /raw %}}
  1034. In that case, the template engine used will be your theme's and the arguments you pass,
  1035. as well as the global context from your ``conf.py``, are available to the template you
  1036. are creating.
  1037. You can use anything defined in your configuration's ``GLOBAL_CONTEXT`` as
  1038. variables in your shortcode template, with a caveat: Because of an unfortunate
  1039. implementation detail (a name conflict), ``data`` is called ``global_data``
  1040. when used in a shortcode.
  1041. If you have some template code that you want to appear in both a template and
  1042. shortcode, you can put the shared code in a separate template and import it in both
  1043. places. Shortcodes can import any template inside ``templates/`` and themes,
  1044. and call any macros defined in those.
  1045. For example, if you define a macro ``foo(x, y)`` in
  1046. ``templates/shared_sc.tmpl``, you can include ``shared_foo.tmpl`` in
  1047. ``templates/special_post.tmpl`` and ``shortcodes/foo.tmpl`` and then call the
  1048. ``${shared_foo.foo(x, y)}`` macro.
  1049. The Global Context and Data files
  1050. ---------------------------------
  1051. There is a ``GLOBAL_CONTEXT`` field in your ``conf.py`` where you can
  1052. put things you want to make available to your templates.
  1053. It will also contain things you put in a ``data/`` directory within your
  1054. site. You can use JSON, YAML or TOML files (with the appropriate file
  1055. extensions: json/js, yaml/yml, toml/tml) that decode to Python dictionaries.
  1056. For example, if you create ``data/foo.json`` containing this:
  1057. .. code:: json
  1058. {"bar": "baz"}
  1059. Then your templates can use things like ``${data['foo']['bar']}`` and
  1060. it will be replaced by "baz".
  1061. Individual posts can also have a data file. Those are specified using the
  1062. ``data`` meta field (path relative to ``conf.py``, can be different in
  1063. different post languages). Those are accessible as eg.
  1064. ``${post.data['bar']}`` in templates. `Template-based shortcodes`_ are a
  1065. good idea in this case.
  1066. Data files can be useful for eg. auto-generated sites, where users provide
  1067. JSON/YAML/TOML files and Nikola generates a large page with data from all data
  1068. files. (This is especially useful with some automatic rebuild feature, like
  1069. those documented in `Deployment`_)
  1070. Data files are also available as ``global_data``, to avoid name conflicts in
  1071. shortcodes. (``global_data`` works everywhere.)
  1072. Redirections
  1073. ------------
  1074. If you need a page to be available in more than one place, you can define redirections
  1075. in your ``conf.py``:
  1076. .. code:: python
  1077. # A list of redirection tuples, [("foo/from.html", "/bar/to.html")].
  1078. #
  1079. # A HTML file will be created in output/foo/from.html that redirects
  1080. # to the "/bar/to.html" URL. notice that the "from" side MUST be a
  1081. # relative URL.
  1082. #
  1083. # If you don't need any of these, just set to []
  1084. REDIRECTIONS = [("index.html", "/weblog/index.html")]
  1085. It's better if you can do these using your web server's configuration, but if
  1086. you can't, this will work.
  1087. Configuration
  1088. -------------
  1089. The configuration file can be used to customize a lot of what Nikola does. Its
  1090. syntax is python, but if you don't know the language, it still should not be
  1091. terribly hard to grasp.
  1092. By default, the ``conf.py`` file in the root of the Nikola website will be used.
  1093. You can pass a different configuration file to by using the ``--conf`` command line switch.
  1094. The default ``conf.py`` you get with Nikola should be fairly complete, and is quite
  1095. commented.
  1096. You surely want to edit these options:
  1097. .. code:: python
  1098. # Data about this site
  1099. BLOG_AUTHOR = "Your Name" # (translatable)
  1100. BLOG_TITLE = "Demo Site" # (translatable)
  1101. SITE_URL = "https://getnikola.com/"
  1102. BLOG_EMAIL = "joe@demo.site"
  1103. BLOG_DESCRIPTION = "This is a demo site for Nikola." # (translatable)
  1104. Some options are marked with a (translatable) comment above or right next to
  1105. them. For those options, two types of values can be provided:
  1106. * a string, which will be used for all languages
  1107. * a dict of language-value pairs, to have different values in each language
  1108. .. note::
  1109. As of version 8.0.3 it is possible to create configuration files which inherit values from other Python files.
  1110. This might be useful if you're working with similar environments.
  1111. Example:
  1112. conf.py:
  1113. .. code:: python
  1114. BLOG_AUTHOR = "Your Name"
  1115. BLOG_TITLE = "Demo Site"
  1116. SITE_URL = "https://yourname.github.io/demo-site
  1117. BLOG_EMAIL = "joe@demo.site"
  1118. BLOG_DESCRIPTION = "This is a demo site for Nikola."
  1119. debug.conf.py:
  1120. .. code:: python
  1121. import conf
  1122. globals().update(vars(conf))
  1123. SITE_URL = "http://localhost:8000/"
  1124. or
  1125. .. code:: python
  1126. from conf import *
  1127. SITE_URL = "http://localhost:8000/"
  1128. Customizing Your Site
  1129. ---------------------
  1130. There are lots of things you can do to personalize your website, but let's see
  1131. the easy ones!
  1132. CSS tweaking
  1133. Using the default configuration, you can create a ``assets/css/custom.css``
  1134. file under ``files/`` or in your theme and then it will be loaded from the
  1135. ``<head>`` blocks of your site pages. Create it and put your CSS code there,
  1136. for minimal disruption of the provided CSS files.
  1137. If you feel tempted to touch other files in assets, you probably will be better off
  1138. with a :doc:`custom theme <theming>`.
  1139. If you want to use LESS_ or Sass_ for your custom CSS, or the theme you use
  1140. contains LESS or Sass code that you want to override, you will need to install
  1141. the `LESS plugin <https://plugins.getnikola.com/#less>`__ or
  1142. `SASS plugin <https://plugins.getnikola.com/#sass>`__ create a ``less`` or
  1143. ``sass`` directory in your site root, put your ``.less`` or ``.scss`` files
  1144. there and a targets file containing the list of files you want compiled.
  1145. .. _LESS: http://lesscss.org/
  1146. .. _Sass: https://sass-lang.com/
  1147. Template tweaking and creating themes
  1148. If you really want to change the pages radically, you will want to do a
  1149. :doc:`custom theme <theming>`.
  1150. Navigation Links
  1151. The ``NAVIGATION_LINKS`` option lets you define what links go in a sidebar or menu
  1152. (depending on your theme) so you can link to important pages, or to other sites.
  1153. The format is a language-indexed dictionary, where each element is a tuple of
  1154. tuples which are one of:
  1155. 1. A (url, text) tuple, describing a link
  1156. 2. A (((url, text), (url, text), (url, text)), title) tuple, describing a submenu / sublist.
  1157. Example:
  1158. .. code:: python
  1159. NAVIGATION_LINKS = {
  1160. DEFAULT_LANG: (
  1161. ('/archive.html', 'Archives'),
  1162. ('/categories/index.html', 'Tags'),
  1163. ('/rss.xml', 'RSS'),
  1164. ((('/foo', 'FOO'),
  1165. ('/bar', 'BAR')), 'BAZ'),
  1166. ),
  1167. }
  1168. .. note::
  1169. 1. Support for submenus is theme-dependent. Only one level of
  1170. submenus is supported.
  1171. 2. Some themes, including the default Bootstrap theme, may
  1172. present issues if the menu is too large. (in Bootstrap, the navbar
  1173. can grow too large and cover contents.)
  1174. 3. If you link to directories, make sure to follow ``STRIP_INDEXES``. If
  1175. it’s set to ``True``, end your links with a ``/``, otherwise end them
  1176. with ``/index.html`` — or else they won’t be highlighted when active.
  1177. There’s also ``NAVIGATION_ALT_LINKS``. Themes may display this somewhere
  1178. else, or not at all. Bootstrap puts it on the right side of the header.
  1179. The ``SEARCH_FORM`` option contains the HTML code for a search form based on
  1180. duckduckgo.com which should always work, but feel free to change it to
  1181. something else.
  1182. Footer
  1183. ``CONTENT_FOOTER`` is displayed, small at the bottom of all pages, I use it for
  1184. the copyright notice. The default shows a text formed using ``BLOG_AUTHOR``,
  1185. ``BLOG_EMAIL``, the date and ``LICENSE``. Note you need to use
  1186. ``CONTENT_FOOTER_FORMATS`` instead of regular str.format or %-formatting,
  1187. for compatibility with the translatable settings feature.
  1188. BODY_END
  1189. This option lets you define a HTML snippet that will be added at the bottom of body.
  1190. The main usage is a Google analytics snippet or something similar, but you can really
  1191. put anything there. Good place for JavaScript.
  1192. SOCIAL_BUTTONS_CODE
  1193. The ``SOCIAL_BUTTONS_CODE`` option lets you define a HTML snippet that will be added
  1194. at the bottom of body. It defaults to a snippet for AddThis, but you can
  1195. really put anything there. See `social_buttons.html` for more details.
  1196. Fancy Dates
  1197. -----------
  1198. Nikola can use various styles for presenting dates.
  1199. DATE_FORMAT
  1200. The date format to use if there is no JS or fancy dates are off. `Compatible with CLDR syntax. <http://cldr.unicode.org/translation/date-time-1/date-time>`_
  1201. LUXON_DATE_FORMAT
  1202. The date format to use with Luxon. A dictionary of dictionaries: the top level is languages, and the subdictionaries are of the format ``{'preset': False, 'format': 'yyyy-MM-dd HH:mm'}``. `Used by Luxon <https://moment.github.io/luxon/docs/manual/formatting>`_ (format can be the preset name, eg. ``'DATE_LONG'``).
  1203. MOMENTJS_DATE_FORMAT (formerly JS_DATE_FORMAT)
  1204. The date format to use if fancy dates are on, and the theme is using Moment.js.
  1205. DATE_FANCINESS = 0
  1206. Fancy dates are off, and DATE_FORMAT is used.
  1207. DATE_FANCINESS = 1
  1208. Dates are recalculated in user’s timezone. Requires JavaScript.
  1209. DATE_FANCINESS = 2
  1210. Dates are recalculated as relative time (eg. 2 days ago). Requires JavaScript.
  1211. In order to use fancy dates, your theme must support them. The built-in Bootstrap family supports it, but other themes might not by default.
  1212. For Mako:
  1213. .. code:: html
  1214. % if date_fanciness != 0:
  1215. %if date_fanciness == 2:
  1216. <!-- Polyfill for relative dates in Safari -- best handled with a CDN -->
  1217. <script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.${luxon_locales[lang]}"></script>
  1218. %endif
  1219. <!-- required scripts -- best handled with bundles -->
  1220. <script src="/assets/js/luxon.min.js"></script>
  1221. <script src="/assets/js/fancydates.js"></script>
  1222. <!-- fancy dates code -->
  1223. <script>
  1224. luxon.Settings.defaultLocale = "${luxon_locales[lang]}";
  1225. fancydates(${date_fanciness}, ${luxon_date_format});
  1226. </script>
  1227. <!-- end fancy dates code -->
  1228. %endif
  1229. For Jinja2:
  1230. .. code:: html
  1231. {% if date_fanciness != 0 %}
  1232. {% if date_fanciness == 2 %}
  1233. <!-- Polyfill for relative dates in Safari -- best handled with a CDN -->
  1234. <script src="https://polyfill.io/v3/polyfill.js?features=Intl.RelativeTimeFormat.%7Elocale.{{ luxon_locales[lang] }}"></script>
  1235. {% endif %}
  1236. <!-- required scripts -- best handled with bundles -->
  1237. <script src="/assets/js/luxon.min.js"></script>
  1238. <script src="/assets/js/fancydates.js"></script>
  1239. <!-- fancy dates code -->
  1240. <script>
  1241. luxon.Settings.defaultLocale = "{{ luxon_locales[lang] }}";
  1242. fancydates({{ date_fanciness }}, {{ luxon_date_format }});
  1243. </script>
  1244. <!-- end fancy dates code -->
  1245. {% endif %}
  1246. Adding Files
  1247. ------------
  1248. Any files you want to be in ``output/`` but are not generated by Nikola (for
  1249. example, ``favicon.ico``) should be placed in ``files/``. Remember that you
  1250. can't have files that collide with files Nikola generates (it will give an
  1251. error).
  1252. .. admonition:: Important
  1253. Don't put any files manually in ``output/``. Ever. Really.
  1254. Maybe someday Nikola will just wipe ``output/`` (when you run ``nikola check -f --clean-files``) and then you will be sorry. So, please don't do that.
  1255. If you want to copy more than one folder of static files into ``output`` you can
  1256. change the FILES_FOLDERS option:
  1257. .. code:: python
  1258. # One or more folders containing files to be copied as-is into the output.
  1259. # The format is a dictionary of "source" "relative destination".
  1260. # Default is:
  1261. # FILES_FOLDERS = {'files': '' }
  1262. # Which means copy 'files' into 'output'
  1263. Custom Themes
  1264. -------------
  1265. If you prefer to have a custom appearance for your site, and modifying CSS
  1266. files and settings (see `Customizing Your Site`_ for details) is not enough,
  1267. you can create your own theme. See the :doc:`theming` and
  1268. :doc:`creating-a-theme` for more details. You can put them in a ``themes/``
  1269. folder and set ``THEME`` to the directory name. You can also put them in
  1270. directories listed in the ``EXTRA_THEMES_DIRS`` configuration variable.
  1271. Getting Extra Themes
  1272. --------------------
  1273. There are a few themes for Nikola. They are available at
  1274. the `Themes Index <https://themes.getnikola.com/>`_.
  1275. Nikola has a built-in theme download/install mechanism to install those themes
  1276. — the ``theme`` command:
  1277. .. code:: console
  1278. $ nikola theme -l
  1279. Themes:
  1280. -------
  1281. blogtxt
  1282. bootstrap3-gradients
  1283. $ nikola theme -i blogtxt
  1284. [2013-10-12T16:46:13Z] NOTICE: theme: Downloading:
  1285. https://themes.getnikola.com/v6/blogtxt.zip
  1286. [2013-10-12T16:46:15Z] NOTICE: theme: Extracting: blogtxt into themes
  1287. And there you are, you now have themes/blogtxt installed. It's very
  1288. rudimentary, but it should work in most cases.
  1289. If you create a nice theme, please share it! You can do it as a pull
  1290. request in the `GitHub repository <https://github.com/getnikola/nikola-themes>`__.
  1291. One other option is to tweak an existing theme using a different color scheme,
  1292. typography and CSS in general. Nikola provides a ``subtheme`` command
  1293. to create a custom theme by downloading free CSS files from https://bootswatch.com
  1294. and https://hackerthemes.com
  1295. .. code:: console
  1296. $ nikola subtheme -n custom_theme -s flatly -p bootstrap4
  1297. [2013-10-12T16:46:58Z] NOTICE: subtheme: Creating 'custom_theme' theme
  1298. from 'flatly' and 'bootstrap4'
  1299. [2013-10-12T16:46:58Z] NOTICE: subtheme: Downloading:
  1300. http://bootswatch.com/flatly/bootstrap.min.css
  1301. [2013-10-12T16:46:58Z] NOTICE: subtheme: Downloading:
  1302. http://bootswatch.com/flatly/bootstrap.css
  1303. [2013-10-12T16:46:59Z] NOTICE: subtheme: Theme created. Change the THEME setting to "custom_theme" to use it.
  1304. Play with it, there's cool stuff there. This feature was suggested by
  1305. `clodo <http://elgalpondebanquito.com.ar>`_.
  1306. Deployment
  1307. ----------
  1308. If you can specify your deployment procedure as a series of commands, you can
  1309. put them in the ``DEPLOY_COMMANDS`` option, and run them with ``nikola deploy``.
  1310. You can have multiple deployment presets. If you run ``nikola deploy``, the
  1311. ``default`` preset is executed. You can also specify the names of presets
  1312. you want to run (eg. ``nikola deploy default``, multiple presets are allowed).
  1313. One caveat is that if any command has a % in it, you should double them.
  1314. Here is an example, from my own site's deployment script:
  1315. .. code:: python
  1316. DEPLOY_COMMANDS = {'default': [
  1317. 'rsync -rav --delete output/ ralsina@lateral.netmanagers.com.ar:/srv/www/lateral',
  1318. 'rdiff-backup output ~/blog-backup',
  1319. "links -dump 'http://www.twingly.com/ping2?url=lateral.netmanagers.com.ar'",
  1320. ]}
  1321. Other interesting ideas are using
  1322. `git as a deployment mechanism <https://toroid.org/git-website-howto>`_ (or any other VCS
  1323. for that matter), using `lftp mirror <https://lftp.yar.ru/>`_ or unison, or Dropbox.
  1324. Any way you can think of to copy files from one place to another is good enough.
  1325. Deploying to GitHub
  1326. ~~~~~~~~~~~~~~~~~~~
  1327. Nikola provides a separate command ``github_deploy`` to deploy your site to
  1328. GitHub Pages. The command builds the site, commits the output to a gh-pages
  1329. branch and pushes the output to GitHub. Nikola uses the `ghp-import command
  1330. <https://github.com/davisp/ghp-import>`_ for this.
  1331. In order to use this feature, you need to configure a few things first. Make
  1332. sure you have ``nikola`` and ``git`` installed on your PATH.
  1333. 1. Initialize a Nikola site, if you haven’t already.
  1334. 2. Initialize a git repository in your Nikola source directory by running:
  1335. .. code:: text
  1336. git init .
  1337. git remote add origin git@github.com:user/repository.git
  1338. 3. Setup branches and remotes in ``conf.py``:
  1339. * ``GITHUB_DEPLOY_BRANCH`` is the branch where Nikola-generated HTML files
  1340. will be deployed. It should be ``gh-pages`` for project pages and
  1341. ``master`` for user pages (user.github.io).
  1342. * ``GITHUB_SOURCE_BRANCH`` is the branch where your Nikola site source will be
  1343. deployed. We recommend and default to ``src``.
  1344. * ``GITHUB_REMOTE_NAME`` is the remote to which changes are pushed.
  1345. * ``GITHUB_COMMIT_SOURCE`` controls whether or not the source branch is
  1346. automatically committed to and pushed. We recommend setting it to
  1347. ``True``, unless you are automating builds with CI (eg. GitHub Actions/GitLab CI).
  1348. 4. Create a ``.gitignore`` file. We recommend adding at least the following entries:
  1349. .. code:: text
  1350. cache
  1351. .doit.db
  1352. __pycache__
  1353. output
  1354. 5. If you set ``GITHUB_COMMIT_SOURCE`` to False, you must switch to your source
  1355. branch and commit to it. Otherwise, this is done for you.
  1356. 6. Run ``nikola github_deploy``. This will build the site, commit the output
  1357. folder to your deploy branch, and push to GitHub. Your website should be up
  1358. and running within a few minutes.
  1359. If you want to use a custom domain, create your ``CNAME`` file in
  1360. ``files/CNAME`` on the source branch. Nikola will copy it to the
  1361. output directory. To add a custom commit message, use the ``-m`` option,
  1362. followed by your message.
  1363. Automated rebuilds (GitHub Actions, GitLab)
  1364. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1365. If you want automated rebuilds and GitHub Pages deployment, allowing you to
  1366. blog from anywhere in the world, you have multiple options:
  1367. * `Automating Nikola rebuilds with GitHub Actions <https://getnikola.com/blog/automating-nikola-rebuilds-with-github-actions.html>`_ (easier for GitHub)
  1368. * `Example Nikola site for GitLab Pages <https://gitlab.com/pages/nikola>`_
  1369. Comments
  1370. --------
  1371. While Nikola creates static sites, there is a minimum level of user interaction you
  1372. are probably expecting: comments.
  1373. Nikola supports several third party comment systems:
  1374. * `DISQUS <https://disqus.com>`_
  1375. * `IntenseDebate <https://www.intensedebate.com/>`_
  1376. * `Muut (Formerly moot) <https://muut.com/>`_
  1377. * `Facebook <https://facebook.com/>`_
  1378. * `Isso <https://posativ.org/isso/>`_
  1379. * `Commento <https://github.com/adtac/commento>`_
  1380. * `Utterances <https://utteranc.es/>`_
  1381. By default it will use DISQUS, but you can change by setting ``COMMENT_SYSTEM``
  1382. to one of "disqus", "intensedebate", "livefyre", "moot", "facebook", "isso", "commento" or "utterances".
  1383. It is also possible to use a comment system added by a plugin, see the
  1384. `Cactus Comments plugin <https://plugins.getnikola.com/#cactuscomments>`_ for an example.
  1385. .. sidebar:: ``COMMENT_SYSTEM_ID``
  1386. The value of ``COMMENT_SYSTEM_ID`` depends on what comment system you
  1387. are using and you can see it in the system's admin interface.
  1388. * For DISQUS, it's called the **shortname**
  1389. * For IntenseDebate, it's the **IntenseDebate site acct**
  1390. * For Muut, it's your **username**
  1391. * For Facebook, you need to `create an app
  1392. <https://developers.facebook.com/apps>`_ (turn off sandbox mode!)
  1393. and get an **App ID**
  1394. * For Isso, it's the URL of your Isso instance (must be world-accessible, encoded with
  1395. Punycode (if using Internationalized Domain Names) and **have a trailing slash**,
  1396. default ``http://localhost:8080/``). You can add custom config options via
  1397. ``GLOBAL_CONTEXT``, e.g., ``GLOBAL_CONTEXT['isso_config'] = {"require-author": "true"}``
  1398. * For Commento, it's the URL of the commento instance as required by the ``serverUrl``
  1399. parameter in commento's documentation.
  1400. * For Utterances, it's the **repo name** (``"org/user"``) on GitHub whose
  1401. issue tracker is used for comments. Additional Utterances configuration
  1402. values can be stored in the ``GLOBAL_CONTEXT``, e.g.,
  1403. ``GLOBAL_CONTEXT['utterances_config'] = {"issue-term": "title",
  1404. "label": "Comments", "theme": "github-light", "crossorigin": "anonymous")``.
  1405. To use comments in a visible site, you should register with the service and
  1406. then set the ``COMMENT_SYSTEM_ID`` option.
  1407. I recommend 3rd party comments, and specially DISQUS because:
  1408. 1) It doesn't require any server-side software on your site
  1409. 2) They offer you a way to export your comments, so you can take
  1410. them with you if you need to.
  1411. 3) It's free.
  1412. 4) It's damn nice.
  1413. You can disable comments for a post by adding a "nocomments" metadata field to it:
  1414. .. code:: restructuredtext
  1415. .. nocomments: True
  1416. .. admonition:: DISQUS Support
  1417. In some cases, when you run the test site, you won't see the comments.
  1418. That can be fixed by adding the disqus_developer flag to the templates
  1419. but it's probably more trouble than it's worth.
  1420. .. admonition:: Moot Support
  1421. Moot doesn't support comment counts on index pages, and it requires adding
  1422. this to your ``conf.py``:
  1423. .. code-block:: python
  1424. BODY_END = """
  1425. <script src="//cdn.moot.it/1/moot.min.js"></script>
  1426. """
  1427. EXTRA_HEAD_DATA = """
  1428. <link rel="stylesheet" type="text/css" href="//cdn.moot.it/1/moot.css">
  1429. <meta name="viewport" content="width=device-width">
  1430. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  1431. """
  1432. .. admonition:: Facebook Support
  1433. You need jQuery, but not because Facebook wants it (see Issue
  1434. #639).
  1435. .. admonition:: Utterances Support
  1436. You can copy the configuration options from the `Utterances setup page
  1437. <https://utteranc.es>`_ into ``GLOBAL_CONTEXT['utterances_config']``,
  1438. except for ``repo``, which should be set as ``COMMENT_SYSTEM_ID``. Note
  1439. that the either ``issue-term`` or ``issue-number`` must be provided. All
  1440. other Utterances configuration options are optional.
  1441. Images and Galleries
  1442. --------------------
  1443. To create an image gallery, all you have to do is add a folder inside ``galleries``,
  1444. and put images there. Nikola will take care of creating thumbnails, index page, etc.
  1445. If you click on images on a gallery, or on images with links in post, you will
  1446. see a bigger image, thanks to the excellent `baguetteBox
  1447. <https://feimosi.github.io/baguetteBox.js/>`_. If don’t want this behavior, add an
  1448. ``.islink`` class to your link.
  1449. The gallery pages are generated using the ``gallery.tmpl`` template, and you can
  1450. customize it there (you could switch to another lightbox instead of baguetteBox, change
  1451. its settings, change the layout, etc.).
  1452. Images in galleries may be provided with captions and given a specific
  1453. ordering, by creating a file in the gallery directory called ``metadata.yml``.
  1454. This YAML file should contain a ``name`` field for each image in the gallery
  1455. for which you wish to provide either a caption or specific ordering. You can also
  1456. create localized versions (``metadata.xx.yml``).
  1457. Only one ``metadata.yml`` is needed per gallery. Here is an example, showing names,
  1458. captions and ordering. ``caption`` and ``order`` are given special treatment,
  1459. anything else is available to templates, as keys of ``photo_array`` images.
  1460. .. code:: yaml
  1461. ---
  1462. name: ready-for-the-acid-wash.jpg
  1463. ---
  1464. name: almost-full.jpg
  1465. caption: The pool is now almost full
  1466. ---
  1467. name: jumping-in.jpg
  1468. caption: We're enjoying the new pool already
  1469. order: 4
  1470. ---
  1471. name: waterline-tiles.jpg
  1472. order: 2
  1473. custom: metadata is supported
  1474. ---
  1475. Images to be used in normal posts can be placed in the ``images`` folder. These
  1476. images will be processed and have thumbnails created just as for galleries, but will
  1477. then be copied directly to the corresponding path in the ``output`` directory, so you
  1478. can reference it from whatever page you like, most easily using the ``thumbnail``
  1479. reST extension. If you don't want thumbnails, just use the ``files`` folder instead.
  1480. The ``conf.py`` options affecting images and gallery pages are these:
  1481. .. code:: python
  1482. # One or more folders containing galleries. The format is a dictionary of
  1483. # {"source": "relative_destination"}, where galleries are looked for in
  1484. # "source/" and the results will be located in
  1485. # "OUTPUT_PATH/relative_destination/gallery_name"
  1486. # Default is:
  1487. GALLERY_FOLDERS = {"galleries": "galleries"}
  1488. # More gallery options:
  1489. THUMBNAIL_SIZE = 180
  1490. MAX_IMAGE_SIZE = 1280
  1491. USE_FILENAME_AS_TITLE = True
  1492. EXTRA_IMAGE_EXTENSIONS = []
  1493. # Use a thumbnail (defined by ".. previewimage:" in the gallery's index) in
  1494. # list of galleries for each gallery
  1495. GALLERIES_USE_THUMBNAIL = False
  1496. # Image to use as thumbnail for those galleries that don't have one
  1497. # None: show a grey square
  1498. # '/url/to/file': show the image in that url
  1499. GALLERIES_DEFAULT_THUMBNAIL = None
  1500. # If set to False, it will sort by filename instead. Defaults to True
  1501. GALLERY_SORT_BY_DATE = True
  1502. # Folders containing images to be used in normal posts or pages.
  1503. # IMAGE_FOLDERS is a dictionary of the form {"source": "destination"},
  1504. # where "source" is the folder containing the images to be published, and
  1505. # "destination" is the folder under OUTPUT_PATH containing the images copied
  1506. # to the site. Thumbnail images will be created there as well.
  1507. IMAGE_FOLDERS = {'images': 'images'}
  1508. # Images will be scaled down according to IMAGE_THUMBNAIL_SIZE and MAX_IMAGE_SIZE
  1509. # options, but will have to be referenced manually to be visible on the site
  1510. # (the thumbnail has ``.thumbnail`` added before the file extension by default,
  1511. # but a different naming template can be configured with IMAGE_THUMBNAIL_FORMAT).
  1512. IMAGE_THUMBNAIL_SIZE = 400
  1513. IMAGE_THUMBNAIL_FORMAT = '{name}.thumbnail{ext}'
  1514. If you add a reST file in ``galleries/gallery_name/index.txt`` its contents will be
  1515. converted to HTML and inserted above the images in the gallery page. The
  1516. format is the same as for posts. You can use the ``title``, ``previewimage``, and
  1517. ``status`` metadata fields to change how the gallery is shown.
  1518. If the ``status`` is ``private``, ``draft``, or ``publish_later``, the
  1519. gallery will not appear in the index, the RSS feeds, nor in the sitemap.
  1520. If you add some image filenames in ``galleries/gallery_name/exclude.meta``, they
  1521. will be excluded in the gallery page.
  1522. If ``USE_FILENAME_AS_TITLE`` is True the filename (parsed as a readable string)
  1523. is used as the photo caption. If the filename starts with a number, it will
  1524. be stripped. For example ``03_an_amazing_sunrise.jpg`` will be render as *An amazing sunrise*.
  1525. Here is a `demo gallery </galleries/demo>`_ of historic, public domain Nikola
  1526. Tesla pictures taken from `this site <https://kerryr.net/pioneers/gallery/tesla.htm>`_.
  1527. Embedding Images
  1528. ~~~~~~~~~~~~~~~~
  1529. Assuming that you have your pictures stored in a folder called ``images`` (as configured above),
  1530. you can embed the same in your posts with the following reST directive:
  1531. .. code:: rest
  1532. .. image:: /images/tesla.jpg
  1533. Which is equivalent to the following HTML code:
  1534. .. code:: html
  1535. <img src="/images/tesla.jpg">
  1536. Please take note of the leading forward-slash ``/`` which refers to the root
  1537. output directory. (Make sure to use this even if you’re not deploying to
  1538. web server root.)
  1539. You can also use thumbnails with the ``.. thumbnail::`` reST directive. For
  1540. more details, and equivalent HTML code, see `Thumbnails`_.
  1541. Handling EXIF Data
  1542. ------------------
  1543. Your images contain a certain amount of extra data besides the image itself,
  1544. called the `EXIF metadata. <https://en.wikipedia.org/wiki/Exchangeable_image_file_format>`__
  1545. It contains information about the camera you used to take the picture, when it was taken,
  1546. and maybe even the location where it was taken.
  1547. This is both useful, because you can use it in some apps to locate all the pictures taken
  1548. in a certain place, or with a certain camera, but also, since the pictures Nikola
  1549. publishes are visible to anyone on the Internet, a privacy risk worth considering
  1550. (Imagine if you post pictures taken at home with GPS info, you are publishing your
  1551. home address!)
  1552. Nikola has some support for managing it, so let's go through a few scenarios to
  1553. see which one you prefer.
  1554. Strip all EXIF data
  1555. ~~~~~~~~~~~~~~~~~~~
  1556. Do this if you want to be absolutely sure that no sensitive information should ever leak:
  1557. .. code:: python
  1558. PRESERVE_EXIF_DATA = False
  1559. EXIF_WHITELIST = {}
  1560. Preserve all EXIF data
  1561. ~~~~~~~~~~~~~~~~~~~~~~
  1562. Do this if you really don't mind people knowing where pictures were taken, or camera settings:
  1563. .. code:: python
  1564. PRESERVE_EXIF_DATA = True
  1565. EXIF_WHITELIST = {'*': '*'}
  1566. Preserve some EXIF data
  1567. ~~~~~~~~~~~~~~~~~~~~~~~
  1568. Do this if you really know what you are doing. EXIF data comes separated in a few IFD blocks.
  1569. The most common ones are:
  1570. 0th
  1571. Information about the image itself
  1572. Exif
  1573. Information about the camera and the image
  1574. 1st
  1575. Information about embedded thumbnails (usually nothing)
  1576. thumbnail
  1577. An embedded thumbnail, in JPEG format (usually nothing)
  1578. GPS
  1579. Geolocation information about the image
  1580. Interop
  1581. Not too interesting at this point.
  1582. Each IFD in turn contains a number of tags. For example, 0th contains a ImageWidth tag.
  1583. You can tell Nikola exactly which IFDs to keep, and within each IFD, which tags to keep,
  1584. using the EXIF_WHITELIST option.
  1585. Let's see an example:
  1586. .. code:: python
  1587. PRESERVE_EXIF_DATA = True
  1588. EXIF_WHITELIST = {
  1589. "0th": ["Orientation", "ImageWidth", "ImageLength"],
  1590. "Interop": "*",
  1591. }
  1592. So, we preserve EXIF data, and the whitelisted IFDs are "0th" and "Interop". That means
  1593. GPS, for example, will be totally deleted.
  1594. Then, for the Interop IFD, we keep everything, and for the 0th IFD we only keep three tags,
  1595. listed there.
  1596. There is a huge number of EXIF tags, described in `the standard <http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf>`__
  1597. Handling ICC Profiles
  1598. ---------------------
  1599. Your images may contain `ICC profiles. <https://en.wikipedia.org/wiki/ICC_profile>`__ These describe the color space in which the images were created or captured.
  1600. Most desktop web browsers can use embedded ICC profiles to display images accurately. As of early 2018 few mobile browsers consider ICC profiles when displaying images. A notable exception is Safari on iOS.
  1601. By default Nikola strips out ICC profiles when preparing images for your posts and galleries. If you want Nikola to preserve ICC profiles, add this in your ``conf.py``:
  1602. .. code:: python
  1603. PRESERVE_ICC_PROFILES = True
  1604. You may wish to do this if, for example, your site contains JPEG images that use a wide-gamut profile such as "Display P3".
  1605. Post Processing Filters
  1606. -----------------------
  1607. You can apply post processing to the files in your site, in order to optimize them
  1608. or change them in arbitrary ways. For example, you may want to compress all CSS
  1609. and JS files using yui-compressor.
  1610. To do that, you can use the provided helper adding this in your ``conf.py``:
  1611. .. code:: python
  1612. FILTERS = {
  1613. ".css": ["filters.yui_compressor"],
  1614. ".js": ["filters.yui_compressor"],
  1615. }
  1616. Where ``"filters.yui_compressor"`` points to a helper function provided by Nikola in the
  1617. ``filters`` module. You can replace that with strings describing command lines, or
  1618. arbitrary python functions.
  1619. If there's any specific thing you expect to be generally useful as a filter, contact
  1620. me and I will add it to the filters library so that more people use it.
  1621. The currently available filters are:
  1622. .. sidebar:: Creating your own filters
  1623. You can use any program name that works in place as a filter, like ``sed -i``
  1624. and you can use arbitrary Python functions as filters, too.
  1625. If your program doesn't run in-place, then you can use Nikola's ``runinplace`` function (from the ``filters`` module).
  1626. For example, this is how the yui_compressor filter is implemented:
  1627. .. code-block:: python
  1628. from nikola.filters import runinplace
  1629. def yui_compressor(infile):
  1630. return runinplace(r'yui-compressor --nomunge %1 -o %2', infile)
  1631. You can turn any function into a filter using ``apply_to_text_file`` (for
  1632. text files to be read in UTF-8) and ``apply_to_binary_file`` (for files to
  1633. be read in binary mode).
  1634. As a silly example, this would make everything uppercase and totally break
  1635. your website:
  1636. .. code-block:: python
  1637. import string
  1638. from nikola.filters import apply_to_text_file
  1639. FILTERS = {
  1640. ".html": [apply_to_text_file(string.upper)]
  1641. }
  1642. filters.html_tidy_nowrap
  1643. Prettify HTML 5 documents with `tidy5 <https://www.html-tidy.org/>`_
  1644. filters.html_tidy_wrap
  1645. Prettify HTML 5 documents wrapped at 80 characters with `tidy5 <https://www.html-tidy.org/>`_
  1646. filters.html_tidy_wrap_attr
  1647. Prettify HTML 5 documents and wrap lines and attributes with `tidy5 <https://www.html-tidy.org/>`_
  1648. filters.html_tidy_mini
  1649. Minify HTML 5 into smaller documents with `tidy5 <https://www.html-tidy.org/>`_
  1650. filters.html_tidy_withconfig
  1651. Run `tidy5 <https://www.html-tidy.org/>`_ with ``tidy5.conf`` as the config file (supplied by user)
  1652. filters.html5lib_minify
  1653. Minify HTML5 using html5lib_minify
  1654. filters.html5lib_xmllike
  1655. Format using html5lib
  1656. filters.typogrify
  1657. Improve typography using `typogrify <https://github.com/mintchaos/typogrify>`__
  1658. filters.typogrify_sans_widont
  1659. Same as typogrify without the widont filter
  1660. filters.typogrify_custom
  1661. Run typogrify with a custom set of filters or ignored HTML elements. Takes one or
  1662. both of the arguments ``typogrify_filters`` or ``ignore_tags``. ``typogrify_filters``
  1663. must be a list of typogrify filter callables to run. ``ignore_tags`` must be a list
  1664. of strings specifying HTML tags, CSS classes (prefixed with ``.``), tag ``id`` names
  1665. (prefixed with ``#``), or a tag and a class or id. The following code should be
  1666. placed in ``conf.py``.
  1667. .. code-block:: python
  1668. from nikola.filters import typogrify_custom
  1669. import functools
  1670. # This filter will ignore HTML elements with the CSS class "typo-ignore"
  1671. FILTERS = {
  1672. ".html": [functools.partial(typogrify_custom, ignore_tags=[".typo-ignore"])]
  1673. }
  1674. # Alternatively, to specify ``typogrify_filters``
  1675. import typogrify.filters as typo
  1676. FILTERS = {
  1677. ".html": [functools.partial(typogrify_custom, typogrify_filters=[typo.amp])]
  1678. }
  1679. The default value for ``typogrify_filters`` is
  1680. ``[typo.amp, typo.widont, typo.smartypants, typo.caps, typo.initial_quotes]`` and the
  1681. default value for ``ignore_tags`` is ``["title", ".math"]``. If ``ignore_tags`` is
  1682. specified, the default tags will be appended to the supplied list. See the
  1683. `documentation <https://github.com/mintchaos/typogrify/blob/master/typogrify/filters.py#L8-L14>`__
  1684. for the ``process_ignores`` function in typogrify.
  1685. filters.minify_lines
  1686. **THIS FILTER HAS BEEN TURNED INTO A NOOP** and currently does nothing.
  1687. filters.normalize_html
  1688. Pass HTML through LXML to normalize it. For example, it will resolve ``&quot;`` to actual
  1689. quotes. Usually not needed.
  1690. filters.yui_compressor
  1691. Compress CSS/JavaScript using `YUI compressor <https://yui.github.io/yuicompressor/>`_
  1692. filters.closure_compiler
  1693. Compile, compress, and optimize JavaScript `Google Closure Compiler <https://developers.google.com/closure/compiler/>`_
  1694. filters.optipng
  1695. Compress PNG files using `optipng <http://optipng.sourceforge.net/>`_
  1696. filters.jpegoptim
  1697. Compress JPEG files using `jpegoptim <https://www.kokkonen.net/tjko/projects.html>`_
  1698. filters.cssminify
  1699. Minify CSS using https://cssminifier.com/ (requires Internet access)
  1700. filters.jsminify
  1701. Minify JS using https://javascript-minifier.com/ (requires Internet access)
  1702. filters.jsonminify
  1703. Minify JSON files (strip whitespace and use minimal separators).
  1704. filters.xmlminify
  1705. Minify XML files. Suitable for Nikola’s sitemaps and Atom feeds.
  1706. filters.add_header_permalinks
  1707. Add links next to every header, Sphinx-style. You will need to add styling for the `headerlink` class,
  1708. in `custom.css`, for example:
  1709. .. code:: css
  1710. /* Header permalinks */
  1711. h1:hover .headerlink, h2:hover .headerlink,
  1712. h3:hover .headerlink, h4:hover .headerlink,
  1713. h5:hover .headerlink, h6:hover .headerlink {
  1714. display: inline;
  1715. }
  1716. .headerlink {
  1717. display: none;
  1718. color: #ddd;
  1719. margin-left: 0.2em;
  1720. padding: 0 0.2em;
  1721. }
  1722. .headerlink:hover {
  1723. opacity: 1;
  1724. background: #ddd;
  1725. color: #000;
  1726. text-decoration: none;
  1727. }
  1728. Additionally, you can provide a custom list of XPath expressions which should be used for finding headers (``{hx}`` is replaced by headers h1 through h6).
  1729. This is required if you use a custom theme that does not use ``"e-content entry-content"`` as a class for post and page contents.
  1730. .. code:: python
  1731. # Default value:
  1732. HEADER_PERMALINKS_XPATH_LIST = ['*//div[@class="e-content entry-content"]//{hx}']
  1733. # Include *every* header (not recommended):
  1734. # HEADER_PERMALINKS_XPATH_LIST = ['*//{hx}']
  1735. filters.deduplicate_ids
  1736. Prevent duplicated IDs in HTML output. An incrementing counter is added to
  1737. offending IDs. If used alongside ``add_header_permalinks``, it will fix
  1738. those links (it must run **after** that filter)
  1739. IDs are numbered from the bottom up, which is useful for indexes (updates
  1740. appear at the top). There are exceptions, which may be configured using
  1741. ``DEDUPLICATE_IDS_TOP_CLASSES`` — if any of those classes appears sin the
  1742. document, the IDs are rewritten top-down, which is useful for posts/pages
  1743. (updates appear at the bottom).
  1744. Note that in rare cases, permalinks might not always be *permanent* in case
  1745. of edits.
  1746. .. code:: python
  1747. DEDUPLICATE_IDS_TOP_CLASSES = ('postpage', 'storypage')
  1748. You can also use a file blacklist (``HEADER_PERMALINKS_FILE_BLACKLIST``),
  1749. useful for some index pages. Paths include the output directory (eg.
  1750. ``output/index.html``)
  1751. You can apply filters to specific posts or pages by using the ``filters`` metadata field:
  1752. .. code:: restructuredtext
  1753. .. filters: filters.html_tidy_nowrap, "sed s/foo/bar %s"
  1754. Please note that applying custom filters (not those provided via Nikola's filter module)
  1755. via metadata only works for filters implemented via external programs like in that `sed` example.
  1756. Optimizing Your Website
  1757. -----------------------
  1758. One of the main goals of Nikola is to make your site fast and light. So here are a few
  1759. tips we have found when setting up Nikola with Apache. If you have more, or
  1760. different ones, or about other web servers, please share!
  1761. 1. Use a speed testing tool. I used Yahoo's YSlow but you can use any of them, and
  1762. it's probably a good idea to use more than one.
  1763. 2. Enable compression in Apache:
  1764. .. code:: apache
  1765. AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
  1766. 3. If even after you did the previous step the CSS files are not sent compressed:
  1767. .. code:: apache
  1768. AddType text/css .css
  1769. 4. Optionally you can create static compressed copies and save some CPU on your server
  1770. with the GZIP_FILES option in Nikola.
  1771. 5. The bundles Nikola plugin can drastically decrease the number of CSS and JS files your site fetches.
  1772. 6. Through the filters feature, you can run your files through arbitrary commands, so that images
  1773. are recompressed, JavaScript is minimized, etc.
  1774. 7. The USE_CDN option offloads standard JavaScript and CSS files to a CDN so they are not
  1775. downloaded from your server.
  1776. Math
  1777. ----
  1778. Nikola supports math input via MathJax (by default) or KaTeX. It is activated
  1779. via the math roles and directives of reStructuredText and the usual LaTeX
  1780. delimiters for other input formats.
  1781. Configuration
  1782. ~~~~~~~~~~~~~
  1783. Nikola uses MathJax by default. If you want to use KaTeX (faster and prettier,
  1784. but may not support every feature yet), set ``USE_KATEX = True`` in
  1785. ``conf.py``.
  1786. To use mathematics in a post, you **must** set the ``has_math`` metadata field
  1787. to ``true``. (Exception: posts that are Jupyter Notebooks are automatically
  1788. marked as math)
  1789. .. Note to editors: the paragraph below uses U+200B, zero-width space. Don’t break it.
  1790. By default, Nikola will accept ``\​(...\​)`` for inline math; ``\​[...\​]`` and
  1791. ``$​$...$​$`` for display math. If you want to use the old ``$...$`` syntax as well
  1792. (which may conflict with running text!), you need to use special config for
  1793. your renderer:
  1794. .. code:: python
  1795. MATHJAX_CONFIG = """
  1796. <script type="text/x-mathjax-config">
  1797. MathJax.Hub.Config({
  1798. tex2jax: {
  1799. inlineMath: [ ['$','$'], ["\\\(","\\\)"] ],
  1800. displayMath: [ ['$$','$$'], ["\\\[","\\\]"] ],
  1801. processEscapes: true
  1802. },
  1803. displayAlign: 'center', // Change this to 'left' if you want left-aligned equations.
  1804. "HTML-CSS": {
  1805. styles: {'.MathJax_Display': {"margin": 0}}
  1806. }
  1807. });
  1808. </script>
  1809. """
  1810. KATEX_AUTO_RENDER = """
  1811. delimiters: [
  1812. {left: "$$", right: "$$", display: true},
  1813. {left: "\\\[", right: "\\\]", display: true},
  1814. {left: "$", right: "$", display: false},
  1815. {left: "\\\(", right: "\\\)", display: false}
  1816. ]
  1817. """
  1818. *(Note: the previous paragraph uses invisible characters to prevent rendering
  1819. TeX for display, so don’t copy the examples with three dots to your posts)*
  1820. Inline usage
  1821. ~~~~~~~~~~~~
  1822. Inline mathematics are produced using the reST `math` **role** or the LaTeX
  1823. backslash-parentheses delimiters:
  1824. Euler’s formula: :math:`e^{ix} = \cos x + i\sin x`
  1825. In reST:
  1826. .. code:: restructuredtext
  1827. Euler’s formula: :math:`e^{ix} = \cos x + i\sin x`
  1828. In HTML and other input formats:
  1829. .. code:: text
  1830. Euler’s formula: \(e^{ix} = \cos x + i\sin x\)
  1831. Note that some input formats (including Markdown) require using **double
  1832. backslashes** in the delimiters (``\\(inline math\\)``). Please check your
  1833. output first before reporting bugs.
  1834. Display usage
  1835. ~~~~~~~~~~~~~
  1836. Display mathematics are produced using the reST `math` **directive** or the
  1837. LaTeX backslash-brackets delimiters:
  1838. .. math::
  1839. \int \frac{dx}{1+ax}=\frac{1}{a}\ln(1+ax)+C
  1840. In reST:
  1841. .. code:: restructuredtext
  1842. .. math::
  1843. \int \frac{dx}{1+ax}=\frac{1}{a}\ln(1+ax)+C
  1844. In HTML and other input formats:
  1845. .. code:: text
  1846. \[\int \frac{dx}{1+ax}=\frac{1}{a}\ln(1+ax)+C\]
  1847. Note that some input formats (including Markdown) require using **double
  1848. backslashes** in the delimiters (``\\[display math\\]``). Please check your
  1849. output first before reporting bugs.
  1850. reStructuredText Extensions
  1851. ---------------------------
  1852. Nikola includes support for a few directives and roles that are not part of docutils, but which
  1853. we think are handy for website development.
  1854. Includes
  1855. ~~~~~~~~
  1856. Nikola supports the standard reStructuredText ``include`` directive, but with a
  1857. catch: filenames are relative to **Nikola site root** (directory with ``conf.py``)
  1858. instead of the post location (eg. ``posts/`` directory)!
  1859. Media
  1860. ~~~~~
  1861. This directive lets you embed media from a variety of sites automatically by just passing the
  1862. URL of the page. For example here are two random videos:
  1863. .. code:: restructuredtext
  1864. .. media:: https://vimeo.com/72425090
  1865. .. media:: https://www.youtube.com/watch?v=wyRpAat5oz0
  1866. It supports Instagram, Flickr, Github gists, Funny or Die, and dozens more, thanks to `Micawber <https://github.com/coleifer/micawber>`_
  1867. YouTube
  1868. ~~~~~~~
  1869. To link to a YouTube video, you need the id of the video. For example, if the
  1870. URL of the video is https://www.youtube.com/watch?v=8N_tupPBtWQ what you need is
  1871. **8N_tupPBtWQ**
  1872. Once you have that, all you need to do is:
  1873. .. code:: restructuredtext
  1874. .. youtube:: 8N_tupPBtWQ
  1875. Supported options: ``height``, ``width``, ``start_at``, ``align`` (one of ``left``,
  1876. ``center``, ``right``) — all are optional. Example:
  1877. .. code:: restructuredtext
  1878. .. youtube:: 8N_tupPBtWQ
  1879. :align: center
  1880. :start_at: 4
  1881. Vimeo
  1882. ~~~~~
  1883. To link to a Vimeo video, you need the id of the video. For example, if the
  1884. URL of the video is https://vimeo.com/20241459 then the id is **20241459**
  1885. Once you have that, all you need to do is:
  1886. .. code:: restructuredtext
  1887. .. vimeo:: 20241459
  1888. If you have internet connectivity when generating your site, the height and width of
  1889. the embedded player will be set to the native height and width of the video.
  1890. You can override this if you wish:
  1891. .. code:: restructuredtext
  1892. .. vimeo:: 20241459
  1893. :height: 240
  1894. :width: 320
  1895. Supported options: ``height``, ``width``, ``align`` (one of ``left``,
  1896. ``center``, ``right``) — all are optional.
  1897. Soundcloud
  1898. ~~~~~~~~~~
  1899. This directive lets you share music from https://soundcloud.com You first need to get the
  1900. ID for the piece, which you can find in the "share" link. For example, if the
  1901. WordPress code starts like this:
  1902. .. code:: text
  1903. [soundcloud url="http://api.soundcloud.com/tracks/78131362" …/]
  1904. The ID is 78131362 and you can embed the audio with this:
  1905. .. code:: restructuredtext
  1906. .. soundcloud:: 78131362
  1907. You can also embed playlists, via the `soundcloud_playlist` directive which works the same way.
  1908. .. soundcloud_playlist:: 9411706
  1909. Supported options: ``height``, ``width``, ``align`` (one of ``left``,
  1910. ``center``, ``right``) — all are optional.
  1911. Code
  1912. ~~~~
  1913. The ``code`` directive has been included in docutils since version 0.9 and now
  1914. replaces Nikola's ``code-block`` directive. To ease the transition, two aliases
  1915. for ``code`` directive are provided: ``code-block`` and ``sourcecode``:
  1916. .. code:: restructuredtext
  1917. .. code-block:: python
  1918. :number-lines:
  1919. print("Our virtues and our failings are inseparable")
  1920. Certain lines might be highlighted via the ``emphasize-lines`` directive:
  1921. .. code:: restructuredtext
  1922. .. code-block:: python
  1923. :emphasize-lines: 3,5
  1924. def some_function():
  1925. interesting = False
  1926. print('This line is highlighted.')
  1927. print('This one is not...')
  1928. print('...but this one is.')
  1929. Line ranges are also supported, such as ``:emphasize-lines: 1-3,5-9,15``.
  1930. Listing
  1931. ~~~~~~~
  1932. To use this, you have to put your source code files inside ``listings`` or whatever folders
  1933. your ``LISTINGS_FOLDERS`` variable is set to fetch files from. Assuming you have a ``foo.py``
  1934. inside one of these folders:
  1935. .. code:: restructuredtext
  1936. .. listing:: foo.py python
  1937. Will include the source code from ``foo.py``, highlight its syntax in python mode,
  1938. and also create a ``listings/foo.py.html`` page (or in another directory, depending on
  1939. ``LISTINGS_FOLDER``) and the listing will have a title linking to it.
  1940. The stand-alone ``listings/`` pages also support Jupyter notebooks, if they are
  1941. supported site-wide. You must have something for ``.ipynb`` in POSTS or PAGES
  1942. for the feature to work.
  1943. Listings support the same options `reST includes`__ support (including
  1944. various options for controlling which parts of the file are included), and also
  1945. a ``linenos`` option for Sphinx compatibility.
  1946. The ``LISTINGS_FOLDER`` configuration variable allows to specify a list of folders where
  1947. to fetch listings from together with subfolder of the ``output`` folder where the
  1948. processed listings should be put in. The default is, ``LISTINGS_FOLDERS = {'listings': 'listings'}``,
  1949. which means that all source code files in ``listings`` will be taken and stored in ``output/listings``.
  1950. Extending ``LISTINGS_FOLDERS`` to ``{'listings': 'listings', 'code': 'formatted-code'}``
  1951. will additionally process all source code files in ``code`` and put the results into
  1952. ``output/formatted-code``.
  1953. __ https://docutils.sourceforge.io/docs/ref/rst/directives.html#including-an-external-document-fragment
  1954. .. note::
  1955. Formerly, ``start-at`` and ``end-at`` options were supported; however,
  1956. they do not work anymore (since v6.1.0) and you should now use ``start-after``
  1957. and ``end-before``, respectively. You can also use ``start-line`` and
  1958. ``end-line``.
  1959. Gist
  1960. ~~~~
  1961. You can easily embed GitHub gists with this directive, like this:
  1962. .. code:: restructuredtext
  1963. .. gist:: 2395294
  1964. Producing this:
  1965. .. gist:: 2395294
  1966. This degrades gracefully if the browser doesn't support JavaScript.
  1967. Thumbnails
  1968. ~~~~~~~~~~
  1969. To include an image placed in the ``images`` folder (or other folders defined in ``IMAGE_FOLDERS``), use the
  1970. ``thumbnail`` directive, like this:
  1971. .. code:: restructuredtext
  1972. .. thumbnail:: /images/tesla.jpg
  1973. :alt: Nikola Tesla
  1974. The small thumbnail will be placed in the page, and it will be linked to the bigger
  1975. version of the image when clicked, using
  1976. `baguetteBox <https://feimosi.github.io/baguetteBox.js/>`_ by default. All options supported by
  1977. the reST `image <https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_
  1978. directive are supported (except ``target``). Providing ``alt`` is recommended,
  1979. as this is the image caption. If a body element is provided, the thumbnail will
  1980. mimic the behavior of the `figure
  1981. <https://docutils.sourceforge.io/docs/ref/rst/directives.html#figure>`_
  1982. directive instead:
  1983. .. code:: restructuredtext
  1984. .. thumbnail:: /images/tesla.jpg
  1985. :alt: Nikola Tesla
  1986. Nikola Tesla, the man that invented the 20th century.
  1987. If you want to include a thumbnail in a non-reST post, you need to produce at
  1988. least this basic HTML:
  1989. .. code:: html
  1990. <a class="reference" href="images/tesla.jpg" alt="Nikola Tesla"><img src="images/tesla.thumbnail.jpg"></a>
  1991. Chart
  1992. ~~~~~
  1993. This directive is a thin wrapper around `Pygal <http://pygal.org/>`_ and will produce charts
  1994. as SVG files embedded directly in your pages.
  1995. Here's an example of how it works:
  1996. .. code:: restructuredtext
  1997. .. chart:: Bar
  1998. :title: 'Browser usage evolution (in %)'
  1999. :x_labels: ["2002", "2003", "2004", "2005", "2006", "2007"]
  2000. 'Firefox', [None, None, 0, 16.6, 25, 31]
  2001. 'Chrome', [None, None, None, None, None, None]
  2002. 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
  2003. 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
  2004. The argument passed next to the directive (Bar in that example) is the type of chart, and can be one of
  2005. Line, StackedLine, Bar, StackedBar, HorizontalBar, XY, DateY, Pie, Radar, Dot, Funnel, Gauge, Pyramid. For
  2006. examples of what each kind of graph is, `check here <http://pygal.org/en/stable/documentation/types/index.html>`_
  2007. It can take *a lot* of options to let you customize the charts (in the example, title and x_labels).
  2008. You can use any option described in `the pygal docs <http://pygal.org/en/stable/documentation/configuration/chart.html>`_
  2009. Finally, the content of the directive is the actual data, in the form of a label and
  2010. a list of values, one series per line.
  2011. You can also specify a ``:data_file:`` option as described in the documentation for the chart shortcut.
  2012. Doc
  2013. ~~~
  2014. This role is useful to make links to other post or page inside the same site.
  2015. Here's an example:
  2016. .. code:: restructuredtext
  2017. Take a look at :doc:`my other post <creating-a-theme>` about theme creating.
  2018. In this case we are giving the portion of text we want to link. So, the result will be:
  2019. Take a look at :doc:`my other post <creating-a-theme>` about theme creating.
  2020. If we want to use the post's title as the link's text, just do:
  2021. .. code:: restructuredtext
  2022. Take a look at :doc:`creating-a-theme` to know how to do it.
  2023. and it will produce:
  2024. Take a look at :doc:`creating-a-theme` to know how to do it.
  2025. The reference in angular brackets should be the `slug` for the target page. It supports a fragment, so
  2026. things like ``<creating-a-theme#starting-from-somewhere>`` should work. You can also use the title, and
  2027. Nikola will slugify it for you, so ``Creating a theme`` is also supported.
  2028. Keep in mind that the important thing is the slug. No attempt is made to check if the fragment points to
  2029. an existing location in the page, and references that don't match any page's slugs will cause warnings.
  2030. Post List
  2031. ~~~~~~~~~
  2032. .. WARNING::
  2033. Any post or page that uses this directive will be considered out of date,
  2034. every time a post is added or deleted, causing maybe unnecessary rebuilds.
  2035. On the other hand, it will sometimes **not** be considered out of date if
  2036. a post content changes, so it can sometimes be shown outdated, in those
  2037. cases, use ``nikola build -a`` to force a total rebuild.
  2038. This directive can be used to generate a list of posts. You could use it, for
  2039. example, to make a list of the latest 5 blog posts, or a list of all blog posts
  2040. with the tag ``nikola``:
  2041. .. code:: restructuredtext
  2042. Here are my 5 latest and greatest blog posts:
  2043. .. post-list::
  2044. :stop: 5
  2045. These are all my posts about Nikola:
  2046. .. post-list::
  2047. :tags: nikola
  2048. Using shortcode syntax (for other compilers):
  2049. .. code:: text
  2050. {{% raw %}}{{% post-list stop=5 %}}{{% /post-list %}}{{% /raw %}}
  2051. The following options are recognized:
  2052. * ``start`` : integer
  2053. The index of the first post to show.
  2054. A negative value like ``-3`` will show the *last* three posts in the
  2055. post-list.
  2056. Defaults to None.
  2057. * ``stop`` : integer
  2058. The index of the last post to show.
  2059. A value negative value like ``-1`` will show every post, but not the
  2060. *last* in the post-list.
  2061. Defaults to None.
  2062. * ``reverse`` : flag
  2063. Reverse the order of the post-list.
  2064. Defaults is to not reverse the order of posts.
  2065. * ``sort``: string
  2066. Sort post list by one of each post's attributes, usually ``title`` or a
  2067. custom ``priority``. Defaults to None (chronological sorting).
  2068. * ``date``: string
  2069. Show posts that match date range specified by this option. Format:
  2070. * comma-separated clauses (AND)
  2071. * clause: attribute comparison_operator value (spaces optional)
  2072. * attribute: year, month, day, hour, month, second, weekday, isoweekday; or empty for full datetime
  2073. * comparison_operator: == != <= >= < >
  2074. * value: integer, 'now', 'today', or dateutil-compatible date input
  2075. * ``tags`` : string [, string...]
  2076. Filter posts to show only posts having at least one of the ``tags``.
  2077. Defaults to None.
  2078. * ``require_all_tags`` : flag
  2079. Change tag filter behaviour to show only posts that have all specified ``tags``.
  2080. Defaults to False.
  2081. * ``categories`` : string [, string...]
  2082. Filter posts to show only posts having one of the ``categories``.
  2083. Defaults to None.
  2084. * ``slugs`` : string [, string...]
  2085. Filter posts to show only posts having at least one of the ``slugs``.
  2086. Defaults to None.
  2087. * ``post_type`` (or ``type``) : string
  2088. Show only ``posts``, ``pages`` or ``all``.
  2089. Replaces ``all``. Defaults to ``posts``.
  2090. * ``all`` : flag
  2091. (deprecated, use ``post_type`` instead)
  2092. Shows all posts and pages in the post list. Defaults to show only posts.
  2093. * ``lang`` : string
  2094. The language of post *titles* and *links*.
  2095. Defaults to default language.
  2096. * ``template`` : string
  2097. The name of an alternative template to render the post-list.
  2098. Defaults to ``post_list_directive.tmpl``
  2099. * ``id`` : string
  2100. A manual id for the post list.
  2101. Defaults to a random name composed by ``'post_list_' + uuid.uuid4().hex``.
  2102. The post list directive uses the ``post_list_directive.tmpl`` template file (or
  2103. another one, if you use the ``template`` option) to generate the list's HTML. By
  2104. default, this is an unordered list with dates and clickable post titles. See
  2105. the template file in Nikola's base theme for an example of how this works.
  2106. The list may fail to update in some cases, please run ``nikola build -a`` with
  2107. the appropriate path if this happens.
  2108. We recommend using pages with dates in the past (1970-01-01) to avoid
  2109. dependency issues.
  2110. If you are using this as a shortcode, flags (``reverse``, ``all``) are meant to be used
  2111. with a ``True`` argument, eg. ``all=True``.
  2112. .. sidebar:: Docutils Configuration
  2113. ReStructured Text is "compiled" by docutils, which supports a number of
  2114. configuration options. It would be difficult to integrate them all into
  2115. Nikola's configuration, so you can just put a ``docutils.conf`` next
  2116. to your ``conf.py`` and any settings in its ``[nikola]`` section will be used.
  2117. More information in the `docutils configuration reference <https://docutils.sourceforge.io/docs/user/config.html>`__
  2118. Importing your WordPress site into Nikola
  2119. -----------------------------------------
  2120. If you like Nikola, and want to start using it, but you have a WordPress blog, Nikola
  2121. supports importing it. Here are the steps to do it:
  2122. 1. Get an XML dump of your site [#]_
  2123. 2. ``nikola import_wordpress mysite.wordpress.2012-12-20.xml``
  2124. After some time, this will create a ``new_site`` folder with all your data. It currently supports
  2125. the following:
  2126. * All your posts and pages
  2127. * Keeps “draft” status
  2128. * Your tags and categories
  2129. * Imports your attachments and fixes links to point to the right places
  2130. * Will try to add redirects that send the old post URLs to the new ones
  2131. * Will give you a URL map so you know where each old post was
  2132. This is also useful for DISQUS thread migration, or server-based 301
  2133. redirects!
  2134. * Allows you to export your comments with each post
  2135. * Exports information on attachments per post
  2136. * There are different methods to transfer the content of your posts:
  2137. - You can convert them to HTML with the WordPress page compiler plugin
  2138. for Nikola. This will format the posts including supported shortcodes
  2139. the same way as WordPress does. Use the ``--transform-to-html`` option
  2140. to convert your posts to HTML.
  2141. If you use this option, you do not need to install the plugin
  2142. permanently. You can ask Nikola to install the plugin into the subdirectory
  2143. ``plugins`` of the current working directory by specifying
  2144. the ``--install-wordpress-compiler`` option.
  2145. - You can leave the posts the way they are and use the WordPress page
  2146. compiler plugin to render them when building your new blog. This also
  2147. allows you to create new posts using the WordPress syntax, or to manually
  2148. add more shortcode plugins later. Use the ``--use-wordpress-compiler``
  2149. option to not touch your posts.
  2150. If you want to use this option, you have to install the plugin permanently.
  2151. You can ask Nikola to install the plugin into your new site by specifying
  2152. the ``--install-wordpress-compiler`` option.
  2153. - You can let Nikola convert your posts to Markdown. This is *not* error
  2154. free, because WordPress uses some unholy mix of HTML and strange things.
  2155. This is the default option and requires no plugins.
  2156. You will find your old posts in ``new_site/posts/post-title.html`` in the first case,
  2157. ``new_site/posts/post-title.wp`` in the second case or ``new_site/posts/post-title.md``
  2158. in the last case if you need to edit or fix any of them.
  2159. Please note that the page compiler currently only supports the ``[code]`` shortcode,
  2160. but other shortcodes can be supported via plugins.
  2161. Also note that the WordPress page compiler is licensed under GPL v2 since
  2162. it uses code from WordPress itself, while Nikola is licensed under the more
  2163. liberal MIT license.
  2164. This feature is a work in progress, and the only way to improve it is to have it used for
  2165. as many sites as possible and make it work better each time, so we are happy to get requests
  2166. about it.
  2167. .. [#] The dump needs to be in 1.2 format. You can check by reading it, it should say
  2168. ``xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"`` near the top of the
  2169. file. If it says ``1.1`` instead of ``1.2`` you will have to update your
  2170. WordPress before dumping.
  2171. Other versions may or may not work.
  2172. Importing to a custom location or into an existing site
  2173. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2174. It is possible to either import into a location you desire or into an already existing Nikola site.
  2175. To do so you can specify a location after the dump:
  2176. .. code:: console
  2177. $ nikola import_wordpress mysite.wordpress.2012-12-20.xml -o import_location
  2178. With this command Nikola will import into the folder ``import_location``.
  2179. If the folder already exists Nikola will not overwrite an existing ``conf.py``.
  2180. Instead a new file with a timestamp at the end of the filename will be created.
  2181. Using Twitter Cards
  2182. -------------------
  2183. Nikola supports Twitter Card summaries, but they are disabled by default.
  2184. Twitter Cards enable you to show additional information in Tweets that link
  2185. to your content.
  2186. Nikola supports `Twitter Cards <https://dev.twitter.com/docs/cards>`_.
  2187. They are implemented to use *Open Graph* tags whenever possible.
  2188. Images displayed come from the `previewimage` meta tag.
  2189. You can specify the card type by using the `card` parameter in TWITTER_CARD.
  2190. To enable and configure your use of Twitter Cards, please modify the
  2191. corresponding lines in your ``conf.py``:
  2192. .. code-block:: python
  2193. TWITTER_CARD = {
  2194. 'use_twitter_cards': True, # enable Twitter Cards
  2195. 'card': 'summary', # Card type, you can also use 'summary_large_image',
  2196. # see https://dev.twitter.com/cards/types
  2197. 'site': '@website', # twitter nick for the website
  2198. 'creator': '@username', # Username for the content creator / author.
  2199. }
  2200. Custom Plugins
  2201. --------------
  2202. You can create your own plugins (see :doc:`extending`) and use them in your own
  2203. site by putting them in a ``plugins/`` folder. You can also put them in
  2204. directories listed in the ``EXTRA_PLUGINS_DIRS`` configuration variable.
  2205. Getting Extra Plugins
  2206. ---------------------
  2207. If you want extra plugins, there is also the `Plugins Index <https://plugins.getnikola.com/>`_.
  2208. Similarly to themes, there is a nice, built-in command to manage them —
  2209. ``plugin``:
  2210. .. code:: console
  2211. $ nikola plugin -l
  2212. Plugins:
  2213. --------
  2214. helloworld
  2215. tags
  2216. $ nikola plugin --install helloworld
  2217. [2013-10-12T16:51:56Z] NOTICE: install_plugin: Downloading: https://plugins.getnikola.com/v6/helloworld.zip
  2218. [2013-10-12T16:51:58Z] NOTICE: install_plugin: Extracting: helloworld into plugins
  2219. plugins/helloworld/requirements.txt
  2220. [2013-10-12T16:51:58Z] NOTICE: install_plugin: This plugin has Python dependencies.
  2221. [2013-10-12T16:51:58Z] NOTICE: install_plugin: Installing dependencies with pip...
  2222. [2013-10-12T16:51:59Z] NOTICE: install_plugin: Dependency installation succeeded.
  2223. [2013-10-12T16:51:59Z] NOTICE: install_plugin: This plugin has a sample config file.
  2224. Contents of the conf.py.sample file:
  2225. # Should the Hello World plugin say “BYE” instead?
  2226. BYE_WORLD = False
  2227. Then you also can uninstall your plugins:
  2228. .. code:: console
  2229. $ nikola plugin --uninstall tags
  2230. [2014-04-15T08:59:24Z] WARNING: plugin: About to uninstall plugin: tags
  2231. [2014-04-15T08:59:24Z] WARNING: plugin: This will delete /home/ralsina/foo/plugins/tags
  2232. Are you sure? [y/n] y
  2233. [2014-04-15T08:59:26Z] WARNING: plugin: Removing /home/ralsina/foo/plugins/tags
  2234. And upgrade them:
  2235. .. code:: console
  2236. $ nikola plugin --upgrade
  2237. [2014-04-15T09:00:18Z] WARNING: plugin: This is not very smart, it just reinstalls some plugins and hopes for the best
  2238. Will upgrade 1 plugins: graphviz
  2239. Upgrading graphviz
  2240. [2014-04-15T09:00:20Z] INFO: plugin: Downloading: https://plugins.getnikola.com/v7/graphviz.zip
  2241. [2014-04-15T09:00:20Z] INFO: plugin: Extracting: graphviz into /home/ralsina/.nikola/plugins/
  2242. [2014-04-15T09:00:20Z] NOTICE: plugin: This plugin has third-party dependencies you need to install manually.
  2243. Contents of the requirements-nonpy.txt file:
  2244. Graphviz
  2245. https://www.graphviz.org/
  2246. You have to install those yourself or through a package manager.
  2247. You can also share plugins you created with the community! Visit the
  2248. `GitHub repository <https://github.com/getnikola/plugins>`__ to find out more.
  2249. You can use the plugins in this repository without installing them into your
  2250. site, by cloning the repository and adding the path of the plugins directory to
  2251. the ``EXTRA_PLUGINS_DIRS`` list in your configuration.
  2252. Advanced Features
  2253. -----------------
  2254. Debugging
  2255. ~~~~~~~~~
  2256. For pdb debugging in Nikola, you should use ``doit.tools.set_trace()`` instead
  2257. of the usual pdb call. By default, doit (and thus Nikola) redirects stdout and
  2258. stderr. Thus, you must use the different call. (Alternatively, you could run
  2259. with ``nikola build -v 2``, which disables the redirections.)
  2260. To show more logging messages, as well as full tracebacks, you need to set an
  2261. environment variable: ``NIKOLA_DEBUG=1``. If you want to only see tracebacks,
  2262. set ``NIKOLA_SHOW_TRACEBACKS=1``.
  2263. Shell Tab Completion
  2264. ~~~~~~~~~~~~~~~~~~~~
  2265. Since Nikola is a command line tool, and this is the 21st century, it's handy to have smart tab-completion
  2266. so that you don't have to type the full commands.
  2267. To enable this, you can use the ``nikola tabcompletion`` command like this,
  2268. depending on your shell:
  2269. .. code:: console
  2270. $ nikola tabcompletion --shell bash --hardcode-tasks > _nikola_bash
  2271. $ nikola tabcompletion --shell zsh --hardcode-tasks > _nikola_zsh
  2272. The ``--hardcode-tasks`` adds tasks to the completion and may need updating periodically.
  2273. Please refer to your shell’s documentation for help on how to use those files.
  2274. License
  2275. -------
  2276. Nikola is released under the `MIT license <https://getnikola.com/license.html>`_, which is a free software license. Some
  2277. components shipped along with Nikola, or required by it are released under
  2278. other licenses.
  2279. If you are not familiar with free software licensing, here is a brief
  2280. explanation (this is NOT legal advice): In general, you can do pretty much
  2281. anything you want — including modifying Nikola, using and redistributing the
  2282. original version or the your modified version. However, if you redistribute
  2283. Nikola to someone else, either a modified version or the original version, the
  2284. full copyright notice and license text must be included in your distribution.
  2285. Nikola is provided “as is”, and the Nikola contributors are not liable for any
  2286. damage caused by the software. Read the `full license text
  2287. <https://getnikola.com/license.html>`_ for details.