### List of categories
In the process of migrating the blog from Drupal to Lektor, the number of tags
has been reduced to 20 (from over 970 in Drupal). For details about this work,
see tpo/web/blog#40008
The items below may now be used in the `categories` field:
| areas of work | topics | operations |
|---------------|----------------|---------------|
| circumvention | advocacy | jobs |
| network | releases | fundraising |
| applications | relays | announcements |
| community | human rights | financials |
| devops | usability | |
| research | reports | |
| metrics | onion services | |
| tails | localization | |
| | global south | |
| | partners | |
When drafting a new blog post, a minimum of one category must be chosen, with a
suggested maximum of three.
### Compress PNG files
When care is taken to minimize the size of web assets, accessibility and
performance is improved, especially for visitors accessing the site from
low bandwidth connections or low-powered devices.
One method to achieve this goal is to use a tool to compress lossless PNG files
using `zopflipng`. The tool can be installed via `apt install zopfli`. To
compress a PNG image, the command may be invoked as such:
zopflipng --filters=0me -m --prefix lead.png
This command will process the input file and save it as `zopfli_lead.png`. The
output message will indicate if the image size was reduced and if so, by what
percentage.
### Comments embedding
When a new blog post is published, a javascript snippet included on the page will
trigger the Discourse forum to create a new topic in the `News` category with the
contents of the new post. In turn, replies to the forum topic will appear
embedded below the blog post.
The configuration for this feature on the Discourse side is located in the Admin
section under **Customize** -> [Embedding][]
The key configuration here is **CSS selector for elements that are allowed in
embeds**. Without the appropriate CSS selectors listed here, some parts of the
blog post may not be imported correctly. There is no documentation of how this
parameter works, but through trial and error we figured out that selectors must
be one or two levels "close" to the actual HTML elements that we need to appear
in the topic. In other words, specifying `main article.blog-post` as a selector
and hoping that all sub-elements will be imported in the topic doesn't work: the
sub-elements themselves must be targeted explicitly.
[Embedding]:https://forum.torproject.net/admin/customize/embedding
## Issues
There is the [tpo/web/blog project](https://gitlab.torproject.org/tpo/web/blog/) for this service, [File][] or
[search][] for issues in the [issue tracker][search].
[File]: https://gitlab.torproject.org/tpo/web/blog//-/issues/new
[search]: https://gitlab.torproject.org/tpo/web/blog//-/issues
## Maintainer, users, and upstream
This website is maintained collaboratively between the TPA web team and the
community team. Users of this service are the general public.
## Monitoring and testing
For monitoring, see [service/static-component#monitoring-and-testing](https://gitlab.torproject.org/tpo/tpa/team/-/wikis/service/static-component#monitoring-and-testing).
There are no automated tests such as spellchecks or dead link checking for this
service. In case of malformed Lektor content files, the build job will fail.
## Logs and metrics
See [service/static-component#logs-and-metrics](https://gitlab.torproject.org/tpo/tpa/team/-/wikis/service/static-component#logs-and-metrics).
## Backups
Backups of this website exist both in the Bacula backups of the GitLab
server (as artifacts) and backups of the
`static-gitlab-shim.torproject.org` server. See the [static components
disaster recovery procedures](static-component.md#disaster-recovery) for how to restore a site.
## Other documentation
* [service/static-component](https://gitlab.torproject.org/tpo/tpa/team/-/wikis/service/static-component)
* [service/static-shim](https://gitlab.torproject.org/tpo/tpa/team/-/wikis/service/static-shim)
* [Lektor documentation](https://www.getlektor.com/docs/)
# Discussion
## Drupal to Lektor migration
The Tor Project runs a [blog](https://blog.torproject.org/) since 2007. It's used to provide an official source of news to the community regarding software releases, fundraising, events and general Tor Project updates. However, there are several outstanding [issues](https://gitlab.torproject.org/tpo/web/blog-trac/-/issues/33115) with the current site, including problems with comment moderation which are not easily fixed using Drupal:
* Hosting the Drupal site at a third party is a significant expense
* Technical maintenance of the blog is a challenge because upstream upgrades frequently cause breakage
* Posts must be drafted with a clunky Javascript HTML editor instead of Markdown
* Moderation is a chore for port authors, causing comments to sometimes linger in the moderation queue
It has been decided to migrate the site to a SSG (static site generator). This is currently listed as [Need to have](https://gitlab.torproject.org/tpo/tpa/team/-/wikis/roadmap/2021#need-to-have) in the 2021 TPA roadmap. (The option to fix the Drupal site was on the table for a short while, but is now abandoned.)
### Goals
We should migrate the site to an SSG as soon as possible.
#### Must have
* Migration of existing blog post and events content (title, author, date, images)
* Preservation of existing URLs (both aliases and node/\* paths)
* RSS/Atom feed for blog posts and events
* Ability to edit migrated content if required (posts and events)
* Ability to comment blog posts (externally)
#### Nice to have
* Migration and continued use of existing blog post tags
* Straightforward content migration
* Archive of existing blog post comments (see rationale [here](https://gitlab.torproject.org/tpo/web/blog-trac/-/issues/33115 at bottom))
* Web-based "admin" interface
* RSS/Atom feeds per-tag and per-author
* [Styleguide](https://styleguide.torproject.org/) compliant template already exists ([Lektor](https://gitlab.torproject.org/tpo/web/template), [Hugo](https://github.com/irl/torproject-hugo))
#### Non-goals
* Author or admin-moderated comments
### Proposed solution
Migrate the site to Lektor, which is already used for https://www.torproject.org, and implement a Discourse instance for discussions, as a replacement for blog comments. This was the solution retained by @hiro for this project, as documented in https://gitlab.torproject.org/tpo/web/blog-trac/-/issues/33115.
There are two options for using Discourse as a blog comments platform:
#### Embedded
Using an embedded-Javascript snippet added in the site template, as documented [here](https://meta.discourse.org/t/embedding-discourse-comments-via-javascript/31963). When a blog post page is opened, the Javascript loads the corresponding topic on the Discourse site. New topics are added to Discourse automatically when new posts are created.
* Pro: comments are visible on the blog, no need to visit/open another site
* Pro: comments can be posted to the Discourse topic directly from within the blog
* Con: posting comments requires a Discourse account
* Con: requires Javascript
#### RSS/Atom feed polling
A Discourse plugin can be configured to poll the blog website RSS/Atom feed at regular intervals and create new topics automatically when a new post is published. It's possible we can predict Discouse topic URLs so that Lektor can generate the required link in the template and insert it at the bottom of blog posts (eg. a "Click here to join the discussion"-type link)
* Pro: no Javascript required on the blog
* Pro: comments not visible directly on the blog
* Con: comments not visible directly on the blog
### Alternatives considered
Note that we settled on using Lektor for the blog, and Discourse as a
comment backend. Those options are therefore not relevant anymore.
* **Hugo** is another friendly SSG, and a [Tor styleguide](https://github.com/irl/torproject-hugo) has been made for it, however its preferable to avoid using different web stacks unless there's a compelling reason for it. There's only one known [Drupal migration script](https://gohugo.io/tools/migrations/#drupal) by it appears to have been created for Drupal 7 and seems unmaintained. In any case it's "assembly required" which isn't much different from hacking a quick script to migrate to Lektor instead.
* **Discourse** might also be an option to completely replace the blog: we could configure https://blog.torproject.org to show content from a specific topic on Discourse. The challenge is that importing content is not as straightforward compared to a SSG where we just need to write text files. Maintaining existing URLs could also be a challenge and would require some form of redirect mapping on `blog.torproject.org`. We would also lose the flexibility to add standalone pages or other forms of content on the blog, ~~such as a calendar view of events~~ [event calendar plugin](https://meta.discourse.org/t/discourse-calendar/97376). ([example](https://www.daemon.com.au/))