---
title: Blog
---

[[_TOC_]]

# Tutorial

Tor project blog is managed through [pantheon.io](https://pantheon.io), which is a Drupal hosting provider.

The site runs Drupal 8.9 with a small set of contrib modules, and is managed and deployed through [Pantheon multidev environment](https://pantheon.io/docs/multidev/).

## Upgrades

Pantheon provides an easy to use "Apply updates" button which merges a couple of commits when upstream releases a new version of the CMS.

However sometimes this causes some merge conflicts or other issues which must be resolved manually.

There are many quirks with the site currently, but due to the decision to migrate, we will only spend time to address security issues.

# Discussion

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://gitweb.torproject.org/project/web/template.git/), [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

 * **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/))

## Proposed web-based workflow for Lektor

Creating new web content for a Lektor site essentially entails editing directories and text files and creating/pushing a new Git commit. This is quite different from the previous workflow in Drupal, so below are steps that can be followed to create new blog posts in Lektor using the GitLab web IDE:

 1. Navigate to the GitLab blog project at https://gitlab.torproject.org/tpo/web/blog
 2. Create a personal fork using the `Fork` button, at top right
 3. Open the personal fork project and click the `Web IDE` button
 4. On the left column, click the `New Directory` icon
 5. Enter `content/blog/<blog-post-slug>` (`blog-post-slug` will be part of the blog post permalink)
 6. In the left column still, navigate to the new directory and open the drop-down menu to the right of the new directory item
 7. Click `New file` to create a new file in that directory
 8. Enter `contents.lr` as the new file name
 9. In the text editor which appears, draft the new blog post (Markdown accepted in `summary` and `body` fields, see below for template)
 10. Upload any images or attachments as needed in `assets/static/images/blog`: in the left column, navigate to that folder, then click the menu button that appears when hovering over the directory name and select `Upload file`
 11. When finished drafting the new blog post, click the blue `Commit` button, lower left
 12. Select `Commit to main branch` and unselect `Start new merge request`
 13. Within a few minutes, the CI should build and upload the draft version at `https://username.pages.torproject.net/blog`
 14. Add more commits if any changes or adjustments are needed
 15. Once the blog post is finalized, create a merge request from the forked project to the main project (eg. From `username/blog:main` into `tpo/web/blog:main`)
 16. When the merge request is reviewed and accepted, the changes are merged and the new blog post is published

### Sample contents.lr

```
title: New Tor Blog
---
author: lavamind
---
pub_date: 2021-08-17
---
summary:
The new Tor Blog is here!
---
body:
The new Tor Blog is here!

The new Tor Blog now runs on top of the Lektor static site generator.
```

The optional field `image` can be specified in order to add a custom banner image. Example: `image: /static/images/blog/filename.png`. Note that the path starts with the forward slash and does not include `assets`. If this field is omitted, the default Tor logo is used.
