Building an Open Source Blogging Platform with Appwrite and Hugo
Tags: opensource, javascript, beginners
Published: 2022-05-18 16:29:00

Have you been in a situation where you think of starting your own blog? Yes? What stops you? The thought of building a blogging site? I have you covered with Appwrite and Hugo! 😎

## 📢 What is Hugo?
Hugo is a static site generator with tonnes of amazing themes to choose from (you can also make your own themes). You can setup Hugo and get it running in a single command `brew install hugo` (choose the one for your OS). To learn more about Hugo, get started from [here](https://gohugo.io/getting-started/).

## 📢 What is Appwrite?
Building a web/mobile solution? Need some help with the backend? [Appwrite](https://appwrite.io/) to the rescue - it is an open-source solution, containing all core APIs to build an application. It helps you build secure apps, faster. Appwrite also handles authentication, realtime databases, file storage, cloud functions, and more with SDKs for web, mobile, and server side languages.
Read about some newly added goodness from [here](https://dev.to/appwrite/announcing-appwrite-014-with-11-cloud-function-runtimes-36f5).

Now that you know what Hugo and Appwrite is, you probably might have guessed what we are going to use it for. Hugo will be our site generator while Appwrite handles the backend.

Let's get started building! 💻

## 📝 Prerequisites
- [Hugo installed](https://gohugo.io/getting-started/installing/)
- [Appwrite installed](https://appwrite.io/docs/installation)

If the installations were successful:
   - You will have Appwrite running in localhost (Go to your browser and enter `http://localhost/auth/signin` , if you get the sign-in page, you are all set)
   - Type the command `hugo version`, if it returns the version, you are good to proceed.

## 🧠 Approach 
By now you must have noticed that the content in Hugo is markdown. Our aim is to store content in a database (this is where we use Appwrite) and use that to generate markdown files which gets listed in our blogging site. 

## 🪜 Steps included
1. Choosing a Hugo theme and installing it 
2. Putting some content and running it on localhost to see how it works
3. Making a project in Appwrite
4. Setting up the Database, adding collections to it
5. Fetching data from Appwrite
6. Converting the data from Appwrite into markdown while Hugo is building
7. Verifying if our content is being reflected in the site

## ▶️ Getting started
- You can follow the [Hugo quick start tutorial](https://gohugo.io/getting-started/quick-start/) to get a site running in few minutes.
- You can choose a different theme from [here](https://themes.gohugo.io/) and download it using the command: `git clone https://github.com/guangmean/Niello.git themes/Niello` in your root directory.

**_Note:_** _I have used Niello for my site, you can choose any_.

This is how your folder will look, after you have downloaded the theme of your choice. 👇
![This is how your folder will look after you have downloaded the theme of your choice](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56r1mg2ubhydiasedcgw.png)

- Once you have signed in to Appwrite, you create a project first, by clicking on **_"Create a project"_**. Give it a name and click **_"Create"_**. 

For example: 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmneukue019xciqyn1bf.png)

-  From the left pane we choose _"Database"_ (which will contain our blog contents) and click on _"Add Database"_ .


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2klbhfv95jlgb6ywz4pw.png)

- Then click on _"Add a collection"_ and give it a name [for e.g Hugo Blog]
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixurdiqvjp3mmj9a5z07.png)
- Once you have a collection created, choose the permission level as _"Document level"_. From the same page, copy the _"Collection ID"_ and keep it handy, we will use this in the later steps.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9v1lq0ty5watpu9gekqv.png)

- A blog consists of two string attributes "Title" and "Body", so we go ahead and add attributes within our Database collection.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ji03qhumzihcgq62vjxp.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n37vshcgmt4k7ozr239x.png)
**_P.S -_** _Choose "New string attribute" and enter the text "Title" in **Attribute ID**_ , also add a "Size". _Repeat the same for "Body"_

- Our next step is to fetch the data from Appwrite, we use the code from [Database API document](https://appwrite.io/docs/client/database?sdk=web-default#databaseListDocuments). We use the `Collection ID` that you have copied in the above step. Create a new `.js` file and add the following lines 👇

```javascript
const sdk = new Appwrite();

sdk
    .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
    .setProject('5df5acd0d48c2') // Your project ID
;

let promise = sdk.database.listDocuments('[COLLECTION_ID]');

promise.then(function (response) {
    console.log(response); // Success
}, function (error) {
    console.log(error); // Failure
});
```
_**Note:**_ _Add some documents before running the above pile of code_

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rghtslnpl3kd77z57jfa.png)

- We have successfully fetched the data, we now move to getting it converted to markdown and let Hugo build from it.
(It is time to use your JavaScript skills) 😉

In the same file(the one created above), where we fetched our collections data, we write the following code:

```javascript
let promise = database.listDocuments('COLLECTION ID');

promise.then(function (response) {
    console.log(response);   

    const template = `
---
title: "{{title}}"  
date: {{date}} 
---
{{desc}}
`;


    for (let i=0;i<=response.documents.length-1;i++){
        const obj= response.documents[i];
        const tempObj ={
            title: obj.Title,
            date: new Date(),
            desc: obj.Body
          }
        
          const op = render(template, tempObj);
          const opPath = `./quickstart/content/posts/${obj.Title.split(" ").join("-")}.md`
          fs.writeFileSync(opPath, op)
    }

}, function (error) {
    console.log(error);
});
```
### Explaining the above block of code: 
1. Putting the fetched data from Appwrite into the markdown template of Hugo
2. Running a loop that puts the above markdown file in the path from where Hugo can build (for this example, the path is: `content\posts`)
3. The loop continues until all the documents from our Appwrite collection is uploaded

The entire code will be something like this: 

```javascript
const sdk = require('node-appwrite');
const fs = require("fs");
const {render} = require("mustache");

// Init SDK
let client = new sdk.Client();

let database = new sdk.Database(client);

client
    .setEndpoint('APPWRITE_ENDPOINT') // Your API Endpoint
    .setProject('APPWRITE_PROJECT') // Your project ID
    .setKey('APPWRITE_API') // Your secret API key
;

let promise = database.listDocuments('COLLECTION_ID');

promise.then(function (response) {
    console.log(response);   

    const template = `
---
title: "{{title}}"  
date: {{date}} 
---
{{desc}}
`;


    for (let i=0;i<=response.documents.length-1;i++){
        const obj= response.documents[i];
        const tempObj ={
            title: obj.Title,
            date: new Date(),
            desc: obj.Body
          }
        
          const op = render(template, tempObj);
          const opPath = `./quickstart/content/posts/${obj.Title.split(" ").join("-")}.md`
          fs.writeFileSync(opPath, op)
    }

}, function (error) {
    console.log(error);
});

```
- Run your file once to make sure everything is working fine, the type `hugo server -D` and your site will be live in: http://localhost:1313/

If you have followed till the end, this is how your site will look 👇

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tnfcjg437sfvjytootxn.png)

## 🪜 Additional steps
1. You can host your site with [Netlify](https://www.netlify.com/) or [GitHub pages](https://pages.github.com/) or any other preferred services
2. You can use your own themes if you wish to

Thank you for reading, hoping this could be of some help!

For any queries/if you want to show me your cool projects, tweet to me: [@Haimantika](https://twitter.com/HaimantikaM)