npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-ghost

v1.3.4

Published

Simple Express Middleware to fetch posts from the Ghost API

Downloads

5

Readme

express-ghost

Simple Express middleware to fetch posts from the Ghost API and cache them into memory.

Use the ghost blogging plattform as headless CMS for your express powered website. Currently only supports posts and pages from the ghost api.

Tag your posts or pages in ghost with your urls and the middleware fetches all posts with this tag and provides them in the res.locals from Express.

For example, you have a page like www.myhomepage.org/aboutus. So you have to tag your post (or page) with "aboutus".

The only expection is the root: www.myhomepage.org/, to get your posts here you have to tag them with "homepage".

Configuration

This project uses nconf under the hood to get the needed credentials to access the ghost api. To get the api credentials you have to provide an "Custom integration" configuration in your ghost backend.

You can provide settings, e.g. in an json file, like nconf.use('settings', { type: 'file', file: __dirname + '/myghostapisettings.json' }); with the following credentials:

{
    "ghost": {
        "enabled": true,
        "url": "https://<my-ghost-host>",
        "key": "<my ghost api key>"
    }
}

In this case, the module initialized the ghost api as soon as the first import with config object given is made: const ghostAPI = require('express-ghost')(config);

Otherwise you have to provide the url and key settings in the init function:

const ghostAPI = require('express-ghost');
ghostAPI.init({ url: "https://<my-ghost-host>", key: "<my ghost api key>" });

Beware, as long as you do not call init (or provide settings via nconf), the answer from the module is always empty.

Usage

Install the middleware in your routes like this:

const express = require('express');
const router = express.Router();
const ghostAPI = require('express-ghost')();

router.use(ghostAPI.postsMiddleware);

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

If you wish to fetch the pages instead, replace the paremter for the use-function with router.use(ghostAPI.pagesMiddleware);. Of course you can use both middlewares. Now you have access to an object in the res.locals.ghostdata

You can use this in your templates, for example with EJS: index-route.js:

const express = require('express');
const router = express.Router();
const ghostAPI = require('express-ghost')();

router.use(ghostAPI.postsMiddleware);

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express', ghostdata: res.locals.ghostdata });
});

module.exports = router;

template.ejs:

<% if (ghostdata && ghostdata.posts) {%>
    <% ghostdata.posts.forEach(function(post) { %>
        <h3><%=post.title</h3>
        <p><%-post.html%></p>
    <% }); %>
<% } %>

The pages array can be accessed under ghostdata.pages.

Purging the cache

Call ghostAPI.purge()

Use the "force" parameter in ghotsAPI.posts({}, true)

You can provide an endpoint in your route definitions like this:

const express = require('express');
const router = express.Router();
const ghost = require('express-ghost');

router.get('/purgeghostcache', function (req, res) {
    ghost.purge();
    res.status(200).json({ pruge: true });
});

module.exports = router;

Switch your route to POST an you can set up a Ghost webhook to clear the cache if some of the content are changing (listen to event site.changed) Beware: This example has some security implications: someone can DDOS your ghost api if not properly secured.

Manipulate the ghost html response

The ghost html reponses contains already classes (and elements) for special content items like galleries (like class="kg-gallery-card"). If you want to get rid of them or replace them with your own (class-) attributes you can provide a parser- (actually filter-) function.

The javascript function has to to accept a string (as first argument) and to return a string. Second argument is optional and can be a tag name, as the function is only executed on posts/pages for the given tag.

Simple use case (in this example no parsing/filtering, just logging):

index-route.js:

const express = require('express');
const router = express.Router();
const ghostAPI = require('express-ghost')();

router.use(ghostAPI.postsMiddleware);
const logGhostHTMLResponse = function(htmlString) {
    console.log('PARSING: ', htmlString);
    return htmlString;
};
ghost.setPostHTMLParser(logGhostHTMLResponse);

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express', ghostdata: res.locals.ghostdata });
});

module.exports = router;

Limitations

Only posts that are tagged with the matching urls (res.originalURL) are fetched. The middleware gets only the latest 10 posts. You can use the api direct with the ghostAPI.posts({}) or ghostAPI.pages({}) function to fetch more than 10 posts/pages. The function takes the same parameters and will provide an promise like the Ghost Content-API.

Long URLs with slashes

Long URLs like /aboutus/team can be used, but you have to replaced the / sign with -. Example: Instead a tag of "abouts/team", the tag must be named "aboutus-team".

Logging

With debug, prefix is: "ghostapi:"