How to Build a Blog with the Apostrophe Blog Module
Tags: webdev, opensource, tutorial, javascript
Published: 2023-03-29 12:41:38

*This step-by-step tutorial shows how to initialize an Apostrophe project, integrate the Blog module, and customize your blog to meet your specific needs and goals.*

[Apostrophe] (https://github.com/apostrophecms/apostrophe) is an open-source website builder and CMS built with modern technologies like Vue.js and Node.js. Apostrophe comes with plenty of features and can also be expanded via [extensions] (https://apostrophecms.com/extensions), JavaScript modules that add new functionality to Apostrophe, such as new content types, widgets, page types, and more.

One of the most popular extensions available for Apostrophe is the Blog module, which allows you to effortlessly add blogging capabilities to an Apostrophe site. Here you will learn what the Apostrophe Blog module is, what benefits it can bring to your site, and how to use it to build a blog!

Let’s start blogging with Apostrophe!


##What Is the Apostrophe Blog Module?
The [Apostrophe Blog] (https://apostrophecms.com/extensions/blog) module is one of several extensions available for Apostrophe. As the name suggests, it is designed to add blogging functionality to an Apostrophe website. Apostrophe Blog gives editors the ability to create and manage blog posts in the content management dashboard, while developers can customize the blog template pages to display content as desired. By integrating Apostrophe Blog into your site, end users will have access to blog pages and date-based filtering features to find the content they are looking for.

The main goal of the Apostrophe Blog module is to provide a simple and easy-to-use solution for adding a blog with filtering functionality to an Apostrophe website. In other words, Apostrophe Blog does not turn your entire website into a blog but adds the ability to introduce a new blog section to it.


##Benefits of Apostrophe Blog
The Apostrophe Blog module can bring several benefits to your website, the three most relevant being:

1. Easy Content Management: Apostrophe Blog offers a simple and intuitive interface for creating and managing blog posts. Editors can easily create blog posts, update them in real time with contextual editing, and add images and videos.
2. Customizable Layouts: The module comes with three built-in templates for displaying and filtering blog posts, but developers can also create their own custom layouts using the powerful Apostrophe template engine. This allows developers to create unique and visually stunning blog pages.
3. Advanced Blog Post Filters: The Apostrophe Blog module streamlines the process of adding a blog section to your site from scratch. Instead of manually configuring everything required, you can take advantage of the [pages and pieces] (https://v3.docs.apostrophecms.org/guide/pages.html) provided by the module to set up a blog in minutes. In particular, the module is equipped with date-based filtering functionality that allows users to select blog posts by year, month, and date.

Now that you know what the Apostrophe Blog module is and why it is such a great tool, all that remains is to see how to integrate it into your website. Let's dive in!


##Set Up a Blog with the Apostrophe Blog Module
Here, you will learn how to integrate Apostrophe Blog into your site. You will start from an Apostrophe boilerplate site and see all the steps necessary to set up the Apostrophe Blog module.

If you are eager to take a look at the code of the final codebase, clone the [GitHub repository supporting with article] (https://github.com/Tonel/apostrophe-blog) with:

```
git clone https://github.com/Tonel/apostrophe-blog
```


####Prerequisites
If you are a Windows user, you first need to set up WSL ([Windows Subsystem for Linux] (https://learn.microsoft.com/en-us/windows/wsl/install)) as explained [in the official docs] (https://v3.docs.apostrophecms.org/cookbook/windows-development.html). To follow this tutorial, you need to meet the Apostrophe 3+ prerequisites below:

* [Node.js 16.x+] (https://nodejs.org/en/): Any LTS version of Node.js greater than or equal to 16 will do.
* [MongoDB 4.2+] (https://www.mongodb.com/docs/manual/administration/install-community/): Follow the link and install the right MongoDB Community Edition app according to your OS. If you are a Windows user, consider [setting up MongoDB as a service] (https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-windows/#follow-the-mongodb-edition-installation-wizard).

Verify that Node.js is working by launching the following command in your terminal:

```
npm node -v
```

This should return the version of Node.js currently installed on your machine, as follows:

```
v18.14.0
```

Similarly, verify that MongoDB is installed with:

```
mongod --version
```

This should print something similar to:

```
db version v6.0.3
Build Info: {
    "version": "6.0.3",
    "gitVersion": "f803681c3ae19817d31958965850193de067c516",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "windows",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```

You can now install the Apostrophe CLI with:

```
npm install -g @apostrophecms/cli
```

This command will install the `[@apostrophecms/cli] (https://www.npmjs.com/package/@apostrophecms/cli)` package globally, giving you access to the `apos` command. With `apos`, you can quickly set up and manage an Apostrophe project. Even though the Apostrophe CLI is not strictly required to deal with an Apostrophe project, it makes everything easier.

You are now ready to set up an Apostrophe 3+ project. Let’s learn how!


####Initialize an Apostrophe Project
First, make sure that MongoDB is running locally by following the [official guide for your OS] (https://www.mongodb.com/docs/manual/administration/install-community/).

Then, enter the folder where you want to create your Apostrophe project and run in the terminal:

```
apos create my-apostrophe-blog
```

This command will initialize an Apostrophe project called `my-apostrophe-blog`. During the process, you will be asked to enter the password for the admin user. Type in a secure password and then store it in a safe place.

The `my-apostrophe-blog` folder should now contain a JavaScript project. Explore it to see what an Apostrophe project looks like.

Enter the `my-apostrophe-blog` folder in the terminal with:

```
cd my-apostrophe-blog
```

Then, start your Apostrophe app with:

```
npm run dev
```

You will see the following warning message:

```
WARNING: No session secret provided, please set the `secret` property of the `session` property of the @apostrophecms/express module in app.js
```

Learn more on how to fix this [here] (https://v3.docs.apostrophecms.org/guide/setting-up.html#creating-a-project).

Your Apostrophe starter project is now running! Visit the `http://localhost:3000/login` page in your browser.


![Apostrophe Blog Login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrabe1tgconlkre9wlk5.png)


Log in with "admin" as the username and the password specified during the initialization process.

You should now be seeing the Apostrophe dashboard that follows:


![Apostrophe dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3f8g1vc2it9uxx3grhzn.png)


Here, you have access to all the [great features offered by ApostropheCMS] (https://v3.docs.apostrophecms.org/guide/introduction.html#what-is-apostrophecms), including website-building capabilities, an intuitive UI for content management, a drafting system, and in-context editing.

You now have an Apostrophe app in place. Let’s learn how to turn it into a blog with the Blog module!


####Integrate the Blog Module
Enter the `my-apostrophe-blog` folder in the terminal and run the command below to install the Blog module:

```
npm install @apostrophecms/blog
```

This will add the `[@apostrophe/blog] (https://www.npmjs.com/package/@apostrophecms/blog)` package to your project’s dependencies.

As with any other Apostrophe module, you must first enable it in the `app.js` file. To configure the Blog module in your Apostrophe project, make sure `app.js` contains the following lines:

```
// app.js

require('apostrophe')({
  shortName: 'my-apostrophe-blog',
  modules: {
    // initial configurations ...

    // add the blog piece to your site
    '@apostrophecms/blog': {},
    // add the blog page type to your site
    '@apostrophecms/blog-page': {}
  },
  // activate the Blog bundle
  bundles: [ '@apostrophecms/blog' ]
});
```

In your Apostrophe dashboard, you will now have access to the “Blog Post” voice menu. Click on it to access the blog post management view below:


![blog post management](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wcm8b7x7aejy5b4b8jt0.gif)


Here, you can add, update, and delete blog posts. Do not worry, you will learn how to do that in the next step.

If you access the “Pages > New Page” view in Apostrophe, you will notice that the “Type” selector only contains the “Default” and “Home” values. In other terms, you cannot create a blog post page from the general view to add new pages.



![new blog page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onit72hu9q1r8hg6qigl.png)


Time to fix this!

The types of pages available in the selector above are defined in the `modules/@apostrophecms/page/index.js` file. Make sure to add the `@apostrophecms/blog-page` type page to the `types` field as follows:

```
module.exports = {
  options: {
    types: [
      // original types...

      // register the blog page type
      {
        name: '@apostrophecms/blog-page',
         label: 'Blog Page'
      }
    ]
  }
};
```

The “Type” selector will now include the “Blog Page” type:


![type selector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pohgpuo9vp10ooxiswj.png)


Let’s now look into a crucial aspect of the Blog module! 

By default, the `@apostrophecms/blog` piece only has the `[default title, slug, and visibility fields] (https://v3.docs.apostrophecms.org/guide/content-schema.html#using-existing-field-groups)` and a custom `publishedAt` field. Since an Apostrophe piece defines the schema associated with a content entity, a blog post instance will only have the information mentioned before. You want to extend this behavior.

Keep in mind that almost everything in Apostrophe is extensible. In particular, you can extend/improve/override features and behaviors of modules by adding specific files in the `modules` folder of your project. When it comes to the main modules and official extensions, you typically have to extend them in the `modules/@apostrophecms` folder. Since the Apostrophe Blog npm package starts with `@apostrophecms`, `modules/@apostrophecms` is where the extension files should be.

To extend the blog post schema with new fields, you will need to define an `index.js` file inside `modules/@apostrophecms/blog`. In Apostrophe, the `index.js` file within a `module` folder specifies the fields available in the content management editor. Any fields defined your local `index.js` file will be added to the fields in the original `index.js` blog extension file. Note that you can also overwrite fields, although this is not common.

Add a `content` field of type [area] (https://v3.docs.apostrophecms.org/reference/field-types/area.html#module-field-definition) to the `@apostrophecms/blog` schema by creating an `index.js` in the `modules/@apostrophecms/blog` folder as follows:

```
// modules/@apostrophecms/blog/index.js

module.exports = {
  fields: {
    // add tge content field to the
    // "@apostrophe/blog" piece definition
    add: {
      content: {
        type: 'area',
        options: {
          widgets: {
            // add support for the rich-text editor
            '@apostrophecms/rich-text': {},
            // add support to multimedia fields in
            // the blog post content
            '@apostrophecms/image': {},
            '@apostrophecms/video': {}
          }
        }
      }
    },
    // add the "content" fields to the
    // "Basics" fields
    group: {
      basics: {
        label: 'Basics',
        fields: [
          'content'
        ]
      }
    }
  }
};
```

An `[area](https://v3.docs.apostrophecms.org/guide/areas-and-widgets.html)` field allows editors to add, edit, and arrange many content [widgets] (https://v3.docs.apostrophecms.org/reference/glossary.html#widget). Specifically, the `content` field enables editors to define rich-text content containing images and videos. Reach the “Blog posts > Add New Blog post” view, and you will have access to a “Content” field as shown below:


![content field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2q9qx5dnkc1dg9autli9.png)


Your editors can now start working on some engaging blog posts. Similarly, you can add other useful fields to your blog post schema, such as tags, a featured image, and author info.

Time to populate your blog with some content!

####Populate Your Blog with Some Posts
First, you need to add a blog section to your site. To do this, create a new page of “Blog Page” type. Click on “Pages > New Page” and initialize your blog home page as follows:


![new page add](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbrjk5k6u3n16ptaov0r.png)


Give your blog home page a `title`, `slug`, and then click the “Publish” button. If you define your slug as “/blog,” all your blog posts will appear under the “/blog” path. 

Now, add some content to your blog. Click on the “Blog posts” option, click “New Blog post,” and define a new blog post as below:


![content field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56pyspgsfc87bik55efa.png)


Click “Publish,” and your article will now be available at `/blog/lorem-ipsum`.

You can use the [Lorem Ipsum generator] (https://loremipsum.io/) to automatically produce sample content for your blogs. Create several articles and assign them different publication dates. Keep in mind that only articles released in the past will be accessible to the users.


![manage blog post index page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o52t7hn5f3st5ntgpy38.png)


Visit the `http://localhost:3000/blog/lorem-ipsum` page to see what the lorem-ipsum blog post defined above looks like:


![lorem-ipsum page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24zf7hkqwa3fbkpqy33u.png)


As you can see the blog post page is not very appealing and does not include any content. Let’s see how to address this! 


####Update Blog Page Templates
Just as you extended the `@apostrophe/blog` piece earlier, you can also extend the `@apostrophe/blog` piece page type. In detail, an [Apostrophe piece page type] (https://v3.docs.apostrophecms.org/guide/piece-pages.html) generally consists of the following two template files:

* `index.html`: Template that defines the index page where to list several instances of a specific piece.
* `show.html`: Template that defines the show page where to display a single instance of a specific piece. 

Since you previously updated the `@apostrophe/blog` piece definition, you need to update the `@apostrophe/blog` piece page type templates accordingly. This is what the original `show.html` template file looks like:

```
{% extends data.outerLayout %}
{% block title %}{{ data.piece.title }}{% endblock %}

{% block main %}
    <h1>{{ data.piece.title }}</h1>
    <p>
    {{ data.piece.publishedAt | date('MMMM D, YYYY') }}
    </p>
{% endblock %}
```

As you can see, this template file only shows the `title` and `publishedAt` blog post info. Note that Apostrophe works with [Nunjucks] (https://mozilla.github.io/nunjucks/) template files. Learn more on this templating engine in [the official docs] (https://mozilla.github.io/nunjucks/templating.html).

Since you also want to show the newly added `content` field in the blog post page, overwrite the original `show.html` file with a new template. To achieve this, add a `show.html` file in the `modules/@apostrophe/blog-page` folder as follows:

```
<!-- modules/@apostrophe/blog-page/show.html -->

{% extends data.outerLayout %}
{% block title %}{{ data.piece.title }}{% endblock %}

{% block main %}
    <h1>{{ data.piece.title }}</h1>
    <div>
        <p>
            {{ data.piece.publishedAt | date('MMMM D, YYYY') }}
        </p>
        <!-- show the blog post content -->
        {% area data.piece, 'content' %}
    </div>
{% endblock %}
```

This template that involves the `content` field of type `area` will replace the original `show.html` file. Find out more about [how to display area fields in templates] (https://v3.docs.apostrophecms.org/reference/field-types/area.html#use-in-templates).

Now, visit the `http://localhost:300/blog/lorem-ipsum` page again.


![blog layout unedited](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/in07ptr9fo7eiln6aotw.png)


The blog post page now displays the content of the article as expected.

Similarly, you can overwrite the `index.html` template file. This represents the home page of the blog and appears as follows:


![blog filter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vx1ts9839c1bzlt52l0p.gif)


As you can see, the page involves some filtering features. If you take a look at [index.html on GitHub] (https://github.com/apostrophecms/blog/blob/main/modules/%40apostrophecms/blog-page/views/index.html), you will notice that it depends on the `[filters.html] (https://github.com/apostrophecms/blog/blob/main/modules/%40apostrophecms/blog-page/views/filters.html)` file. filters.html contains the HTML elements to filter blog posts by year, month, and day. The filtering logic is based on some queries defined in the `[queries.js] (https://github.com/apostrophecms/blog/blob/main/queries.js)` file imported in the `[@apostrophe/blog/index.js] (https://github.com/apostrophecms/blog/blob/main/index.js)` original file. As explained in the [Filtering section of the Blog module page] (https://apostrophecms.com/extensions/blog#filtering-by-year-month-and-day), you can also employ these filters in server-side queries and in REST APIs when [using Apostrophe as a headless CMS] (https://v3.docs.apostrophecms.org/guide/headless-cms.html#using-apostrophe-as-a-headless-cms). 

You can test the filters by clicking on the “2022” link. You will be redirected to `http://localhost:3000/blog?year=2022`, whose list of blog posts will contain only articles released in 2022:


![blog article list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdt9yqg5v3f30epmscs5.png)


By writing very few lines of code, you now have a blog with filtering functionality. This is the true power of the Apostrophe Blog module! Yet, the blog section of your site is still a bit bland visually. Time to make the UI of the blog fresher! 


####Customize the UI of the Blog
Apostrophe allows you to [customize the UI of your templates] (https://v3.docs.apostrophecms.org/guide/front-end-assets.html#adding-front-end-css-and-javascript). Specifically, the `modules/asset/ui` module contains all [SCSS] (https://en.wikipedia.org/wiki/Sass_(stylesheet_language)) files that take care of styling your website. By default, `apos create` initializes your Apostrophe project with some basic `.scss` files. You can remove, overwrite, or ignore them and add new SCSS files.

Let’s learn how to add some style to your Apostrophe blog! 

In the `modules/asset/ui/src/scss` folder, define a new `_blog.scss` file as follows:

```
// modules/asset/ui/src/scss/_blog.scss
    
    .bg-container {
      padding-right: 15px;
      padding-left: 15px;
      margin-right: auto;
      margin-left: auto;
    
      @media (min-width: 576px) {
          width: 540px;
      }
    
      @media (min-width: 768px) {
          width: 720px;
      }
    
      @media (min-width: 992px) {
          width: 960px;
      }
    
      @media (min-width: 1200px) {
          width: 1140px;
      }
    }
    
    .bg-h1 {
      text-align: center;
      margin: 0 0 20px;
    }
    
    .bg-publication-date {
      text-align: center;
      font-style: italic;
      color: #505050;
      font-size: 14px;
      margin-bottom: 25px;
    }
    
    .bg-content {
      font-size: 16px;
    
      p {
        margin-bottom: 30px;
        line-height: 30px;
      }
    }
```

This is just an example, but you can place all your CSS classes here for your blog.

Now, add the following line to the `modules/asset/ui/src/index.scss`:

```
@import './scss/_blog';
```

This will import the `_blog.scss` file defined earlier in the global `index.scss` file, and it will make the CSS classes defined in `_blog.scss` available in the project.

You can add some CSS to the `show.html` file as shown below:

```
<!-- modules/@apostrophe/blog-page/show.html -->

{% extends data.outerLayout %}
{% block title %}{{ data.piece.title }}{% endblock %}

{% block main %}
<div class="bg-container">
    <h1 class="bg-h1">{{ data.piece.title }}</h1>
    <div class="bg-publication-date">
        {{ data.piece.publishedAt | date('MMMM D, YYYY') }}
    </div>
    <div class="bg-content">
        <!-- show the blog post content -->
        {% area data.piece, 'content' %}
    </div>
</div>
{% endblock %}
```

Note that the template file involves the same CSS classes defined in `_blog.scss`.

Here is what the `http://localhost:300/blog/lorem-ipsum` page now looks like:


![blog post with edited layout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ee2o8y0k8e6lfgi33wp8.png)


Much better, don’t you think?

With just a few lines of SCSS code, you have improved the visual appearance of the blog page significantly. Similarly, you can also style the home page of your blog by adding new CSS classes and updating the `index.html` template file accordingly.

The tutorial ends here, but before wrapping up check out the final version of the blog in the [GitHub repo behind this tutorial] (https://github.com/Tonel/apostrophe-blog). Now you know how use the Apostrophe Blog module to create a blog, customize it, style it, and manage its content!

##Conclusion
In this article, you learned what the Apostrophe Blog module is, how to use it to build a blog, and what benefits it can bring to your site. In detail, the Apostrophe Blog module is a quick and easy way to create a powerful and comprehensive blog with several features. Thanks to the extensible nature of Apostrophe, you can also easily customize your blog.

By following this step-by-step tutorial, you saw how to initialize an Apostrophe project, integrate the Blog module, and customize your blog to meet your specific needs and goals. This is all you need to build a blog to engage and inform your audience with great content.

Thanks for reading! We hope this article helped clear your mind. Feel free to reach out to us on [Twitter] (https://twitter.com/apostrophecms) with any comments, questions, or suggestions!


This tutorial was provided by an Apostrophe community member, Antonello Zanini. This article was originally published on the [ApostropheCMS website] (https://apostrophecms.com/).