############################# Migrating From Plone To ABlog ############################# My aspiration to return to blogging thanks to `reStructuredText`_, `ABlog`_ and `GitLab CI/CD`_. I stopped blogging years ago. I was never very good at blogging regularly, I always seem to prefer adding further polish to whatever I'm working on over sharing what I've learned. But it didn't help that my old blogging platform, self-hosted `Plone`_, was too heavy for the job. The maintenance work kept piling up and every time I thought of blogging, I'd remember that ``TODO`` list and then do something else instead. :-/ I want to be very clear. `Plone`_, the open-source enterprise CMS, is a simply awesome piece of software and a remarkable open-source project. The list of features provided is both extensive and powerful and the capacity to extend those features and frameworks to build custom CMS'ish applications is even more powerful. Finally and foremost, being involved in the open-source community that develops and maintains that software ecosystem has been the most rewarding part of my career in software. Lovely people. Plone is, however, laughably overkill for a software developer's professional blog. My intention was `to eat my own dog-food`_ by using the CMS that I spent most of my time working with at the time. That intention is perfectly reasonable but my work stream has mostly moved away from Plone in the intervening years and the maintenance burden is never small for such a large feature set, even if you're using almost none of those features. I'll try to learn the lesson here to moderate the impulse to dog-food. Blogging is writing. Text (as opposed to a WYSIWYG word processor, for example) is the format for writing that least gets in the way when one is proficient with a programmer's editor. Python's magnificent `reStructuredText`_ is the most expressive text markup language out there and provides a number of features that one inevitably needs when doing much more than writing a heading, 3 paragraphs, 2 lists and 5 links. `Sphinx`_ is the lingua franca for writing documentation in the `Python`_ world and beyond, and for very good reason. I've known for some time, given the above, that I wanted to blog in ``reST`` and I also want to become more familiar with Sphinx, so I went looking for static site generators based on Sphinx. I evaluated `ABlog`_ and `Tinkerer`_, both blogging-oriented static site generators based on Sphinx. I like that `ABlog`_ seems to be a little less opinionated and calls itself a Sphinx extension since I may well want to use this platform for static site content beyond just blogging. It also seems like `ABlog`_ is actively maintained while the last release of `Tinkerer`_ was in 2017. Given what I read in a few other reviews and comments I made the call to go with `Ablog`_. Next up I needed to decide whether to preserve my Plone blogging content or start afresh. Given that I'm bad at getting around to blogging, I thought exporting my old posts would help fill things out a but, though one glance at the dates gives that game away. ;-) It also seemed like a fun problem to solve. Given that the target is text files and a static site generator, I decided to write :download:`the export script <./scripts/export_content.py>` oriented towards files on the filesystem and as agnostic about the internals of Plone as possible. I'm pretty happy with it for such a pragmatic bit of "software" and I think it does a surprisingly decent job of capturing as much as possible the data and metadata of Plone content in a format most appropriate for files in a filesystem and oriented to file and text-oriented tools. In particular, it exports text fields the format of the "native" MIME type of that field instance, mostly so that posts I wrote in ``reST`` would remain in that format on export. It will also export multiple, separate file-like fields to separate files preserving any per-field filename if available. For example, the lead images for Plone ``News Item`` instances, were written next to the corresponding ``reST`` file with the original uploaded image ``basename``. Finally, it also uses the FTP/WebDAV support built into Zope to export most, if not all, other fields to a corresponding ``*.properties`` file in RFC822 format. Now that I had files reflecting the Plone representation of the content, I created a new repository, copied the files there and began working on massaging them into `ABlog`_ posts. I learned about `the reST '.. raw:: html' directive`_ for the Plone content I wrote using the WYSIWYG editor and was thus in HTML format in the exported files. It works nicely and some quick shell commands created an ``*.rst`` file corresponding to each ``*.html`` file: .. code-block:: rst .. raw:: html :file: ./{id}.html Thus having ``*.rst`` files for each exported post, it was time to convert them into ABlog posts. I wanted to preserve all metadata from the ``*.properties`` files that corresponded to `ABlog post metadata`_ or could reasonably be added to the ``reST`` surrounding the main content of the post. Again, I'm pretty happy with how much :download:`the import script <./bin/rfc822-to-post>` was able to preserve. I don't think I'll miss any of the excluded metadata: .. code-block:: rst ####### {title} ####### {description} .. raw:: html :file: ./{id}.html .. meta:: :description: {description} :keywords: {subject} .. post:: {creation_date} :tags: {subject} :author: Ross Patterson :redirect: @@redirect-to-uuid/{UID} .. update:: {modification_date} Imported from Plone on {now}. The date for this update is the last modified date in Plone. If any of the above export/import code would be useful to anyone else, LMK and I'll throw it up to a separate GitLab repository under an open-source license along with my VCS history. With all the content showing up nicely in the output from the `ABlog watchdog, auto-rebuild development server`_, I fixed a few formatting issues in the imported content, updated the boilerplate content, and went looking for a theme. I do prefer dark themes but mostly, much to my chagrin, I've noticed that many if not most people seem to think less of you if you show them something with the default theme, even when the person showing you is decidedly *not* a designer. ;-) I found `a dark Solarized theme that extends the default theme`_ and `contributed some fixes`_. It's certainly not perfect, but I like it better than the default and it certainly expresses that this is the blog of a developer. Finally, I created a private GitLab repository and whipped up a simple `GitLab CI/CD`_ configuration that builds and deploys the built static site to GitLab Pages when I push to master. I added some `GitLab redirects`_ for the few paths that changed. BTW, this is one of the nice things about `ABlog`_ so far, most paths stayed the same. I pushed to ``master`` and viola! Do LMK if you find any bugs. This ended up being more complete than I would have expected so I'd love to know of any issues I missed. .. _`Python`: http://www.python.org/ .. _`reStructuredText`: https://docutils.sourceforge.io/rst.html .. _`Sphinx`: https://www.sphinx-doc.org/en/master/ .. _`the reST '.. raw:: html' directive`: https://docutils.sourceforge.io/docs/ref/rst/directives.html#raw-data-pass-through .. _`ABlog`: https://ablog.readthedocs.io/ .. _`ABlog post metadata`: https://ablog.readthedocs.io/manual/posting-and-listing/#directive-post .. _`ABlog watchdog, auto-rebuild development server`: https://ablog.readthedocs.io/manual/watch-yourself-blogging/ .. _`a dark Solarized theme that extends the default theme`: https://git.sr.ht/~sporiff/alabaster-solarised .. _`contributed some fixes`: https://git.sr.ht/~rpatterson/alabaster-solarised/commit/3ea216cecf5756ca631935ba2d3a33d176806d4d .. _`Tinkerer`: http://tinkerer.me/index.html .. _`GitLab CI/CD`: https://docs.gitlab.com/ee/user/project/pages/getting_started/pages_from_scratch.html .. _`GitLab redirects`: https://docs.gitlab.com/13.9/ee/user/project/pages/redirects.html .. _`Plone`: http://plone.org .. _`to eat my own dog-food`: ../../news/about-this-site/ .. meta:: :description: My aspiration to return to blogging thanks to reStructuredText, ABlog and GitLab CI/CD. :keywords: Python, reStructuredText, Sphinx, ABlog, Plone .. post:: Mar 16, 2021 :author: Ross Patterson :tags: Python, reStructuredText, Sphinx, ABlog, Plone