Journey into new Web Tech
Published: 2024-06-20 19:07:18

Today's web offers many new technologies, the core of which is to employ a Content Management tool that the site owner can edit their content. From a development perspective, the next steps would be to pull that content, code the client side scripts and then finally to serve it as a web application.

While there are many tools to accomplish the above, the remainder of this post will outline the tools I chose to develop a site. Another goal is to re-use such work for creating any web applications for prospective clients. For content management, I decided upon Ghost CMS and for Static Site generation, I decided upon Astro.

## Ghost CMS

Besides the installation located at https://ghost.org/docs/install/, the next step with using Ghost CMS, would be to create or use a theme. This has a learning curve to it if creating a new theme. Ghost themes are written using [Handlebars](https://handlebarsjs.com/), another templating language to learn if you have not already done so. Most of the existing themes I have looked at also use gulp to concatenate the CSS files. Ghost has some pretty good [documentation on creating themes](https://ghost.org/docs/themes/).

I have a working theme that I uploaded to [git hub](https://github.com/devdog66/meikos-ghost-theme) so that the reader can follow along for the rest of the post. 

A good practice that I have seen many ghost theme authors do, is to separate concerns meaning to have separate CSS files for certain areas or components of a site. An example of how I did this is below.

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

One CSS file, I chose to name it main.css, imports the other CSS files that gulp will concatenate and minify. Here is how my main.css file looks.

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

Some may find some limitations with Ghost about theming. One such limitation would be with navigation links. Out of the box, there are no multi-level capabilities nor are there ways to assign icons to links if desired. Therefore, I made the choice to hard code the navigation for a site using some placeholders. Another limitation is the seemingly lack of ability to preview the theme. I have tried the [express-handlebars](https://www.npmjs.com/package/express-handlebars) package to do this, however ran into roadblocks with Ghost specific variables and statements. I may revisit that attempt later. Right now the only way I see to preview is to zip up the theme files and upload to the Ghost admin location. Then you can preview it on Ghost.

The project is fairly simple with the following npm steps outlined below.

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

The first step is a utility from Ghost called gscan. This allows you to check the syntax of your .hbs files and the theme overall to make sure it adheres to a valid Ghost theme. Next is the build step that gulp will use to pack the main.css file. Now to create the theme zip file with the npm zip script. It uses gulp again to do this. I chose not to build with this step as sometimes the errors that gscan produces are not detailed enough. If one uploads the zipped theme even with errors, the Ghost admin site will provide more details as to what specifically needs to be fixed.

A final optional step is to copy the theme or assets folder to the next project in Astro. Here is the example of the main site template, default.hbs. 

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

## Astro SSG
As of now, I have a Ghost instance with a theme of my liking and I have created the content on my Ghost instance. My next goal is to pull the content from Ghost CMS and to create the static assets needed for a web site. This is where Astro comes in. I have uploaded another repo to [git hub](https://github.com/devdog66/meikos-astro) for the user to follow along with. 

The project structure looks like the following.

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

The public folder mostly contains the assets sub folder copied from the ghost theme. The src folder is broken down into the following:

- components = *Reusable parts to be included in layouts or pages.*

- content    = *The folder where blogs and pages will be imported to. This follows Astro's content collections instructions.*

- importer   = *This has the script used for importing content.*

- layouts    = *This has the main layout for the site. Can include multiple layouts if desired.*

- pages      = *This contains slugs to render pages or posts.*

The meat of the project is with the importer/index.ts script. It uses an API that needs to be setup in the Ghost instance with an API Key. In order to get Astro and Ghost to work together nicely, some workarounds were needed for this step.

Ghost exports it's format as HTML. Astro is built for Markdown. Therefore the exported content should be stored as .MDX files to work. Next workaround is with the fact that Ghost does not always export well-formed HTML and therefore I was forced to use a tool like sanitize-html to take care of that. I had to use it like below.

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

The layout is pretty simple and mirrors what was used with the default layout for the Ghost theme.

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


The page slug looks like the following and shows how to use the 'page' content collection. 

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


All of this results in a beautiful cover page for a new web site.

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


And there is a list of recent blog posts, including this one. Talk about eating your own dog food.


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