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

stacy

v2.0.0

Published

Automatic static website generator and publisher for Contentful CMS and AWS.

Downloads

16

Readme

Stacy

Stacy is a website generator that combines content from Contentful CMS with Handlebars templates to create the website pages.

Stacy matches Contentful's entry content types with Handlebars templates in your website project in a one-to-one relationship—there is a template for every entry type defined in your Content model. There are two types of entries from Stacy's point of view: page entries and module entries. A page entry combined with its template produces a single website page at a unique URL. Module entries can be included in pages and other modules using Contentful's Reference fields to create reusable pieces of content or simply to provide content and templates structure by breaking it up into smaller pieces.

What makes Stacy different from many existing static website generators is that it supports automatic publishing of the website to an S3 bucket in Amazon Cloud, from where it can be served on the Internet. Stacy deploys special infrastructure in Amazon Cloud which can be connected to Contentful via its Webhooks functionality. When content is updated in your Contentful space, your website's infrastructure deployed by Stacy in Amazon Cloud gets notified and automatically regenerates and republishes only those pages of your website that are affected by the update. No manual website regeneration and redeployment is required.

When using Stacy, your website is an NPM project usually checked in a git repository for version control. The project includes your Handlebars templates and static content (such as CSS stylesheets, images used in the website design, fonts, etc.), while the website content lives in the Contentful space. From the website project the website developers use Stacy command line tool to develop, publish and republish the site. Once the website is published in Amazon Cloud, the content authors work only with Contentful UI.

See Creating a Website with Stacy for a detailed tutorial/walkthrough.

Getting Started

First, you need a Contentful space for your website's content. Once you have that, you can create a new project for your website.

Make sure that you have Node.js version 10.16.3 or newer installed together with npm. If you are going to be publishing the website in Amazon Cloud, you will also need AWS CLI installed.

Start with installing Stacy globally:

npm install -g stacy

In your Contentful space, go to Space settings→API keys and add an API key in Content delivery/preview tokens. Note Space ID and Content Delivery API access token values that you will use to connect your Stacy environment to your Contentful space.

Now, you can generate initial project for your website:

stacy new --cf-space <your space ID> --cf-access-token <your access token> mywebsite

This will create a new project directory named "mywebsite" in the current directory. The "mywebsite" value is known as the site ID. Use a different value that identifies your website. The value should be URL-fiendly (small letters, digits and dashes).

In your project directory, put static content under /static (this gets copied over to your website as-is) and put your entry templates under /templates. The name of the template file (sans the extention) must exactly match the corresponding entry content type in your Contentful Content model. Under /templates, the template files can be organized in subfolders. However, the file names must be unique across all subfolders because they are used to uniquely match templates to entry content types (subfolders in /templates play no role).

Note: Normally, a template, combined with an entry's content, produces HTML. If you need to produce some other type of content, you can add an extension to the template name. For example, page.hbs produces HTML. To produce plain text use page.txt.hbs. This also means that page.hbs and page.html.hbs are the same.

You can now run your website locally for development purposes:

stacy serve

You can see your website at http://localhost:8080/. After you edit any template, static content or content in Contentful, just reload the page.

To stop Stacy local webserver use Ctrl+C.

Run stacy --help to see other available commands.

The content of your project directory you can check in to a git repository such as GitHub or Bitbucket.

Templates

Inside you templates all entry fields are available by the Field ID as defined in your Content model. You can reference them directly in your template. For example:

<h3>{{caption}}</h3>

This will output the value of the entry's caption field. Note, that it's Field ID which is used here and not the field Name.

Stacy adds a few special helpers that you can use in your templates:

  • module <reference field> - Include module entry referenced by the Reference type field. For example, given that you have a field with ID paragraphs and it is a list of references:

    {{#each paragraphs}}{{{module this}}}{{/each}}
  • asset <asset field> - Include the referred asset, such an image. For example:

    {{asset picture}}

    Currently, only image assets are supported, for which an HTML <img> tag is rendered.

  • assetSrc <asset field> - Get URL of the asset. For example:

    <img src="{{assetSrc picture}}">
  • assetTitle <asset field> - Get title of the asset. For example:

    <img src="{{assetSrc picture}}" alt="{{assetTitle picture}}">
  • markdown <long text field> - Render Markdown long text field. For example:

    {{{markdown description}}}

    Note the tripple-braces needed here because the helper generates HTML which needs not to be escaped.

  • richText <rich text field> - Render rich text field. For example:

    {{{richText content}}}

    As with markdown, note the triple-braces.

  • json <field> - Output internal Contentful JSON representation of the field. For example:

    <pre>{{json myField}}</pre>

    This helper may be useful for diagnosing problems.

Content Model

As mentioned above, there is a one-to-one relationship between content types you define in your Contentful space's Content model and templates.

Note: Strictly speaking, you can have more than one template for a given content type to allow generation of different types of files for the same content entry. For example, for content type ID module you could have templates module.html.hbs and module.xml.hbs. First tempplate will produce an HTML file for the entry and the second will produce an XML file.

When you define a content type, note the Api Identifier (also known as content type ID). The template file for the content type will have to have the same name (plus the extention).

There is one requirement for content types for page entries (as opposed to module entries): a page content type must define a required slug field. The value in the field will be determining the name of the generated file when the content entry is combined with the corresponding template. For example, if slug value for a page entry is "index", the generated page will be "/index.html". If the slug is "more/terms", the page will be "/more/terms.html". And so on.

By default, the field ID for the slug field must be slug. The ID can be overridden in the project's stacy.json file. Besides making the slug field required in the content type definition, it is also recommended to associate a custom match pattern validator with it to ensure the field value's specific format. The regular expression for the validator can be ^\w[\w-]*(/\w[\w-]*)*$.

Publishing in Amazon Cloud

When you are ready to deploy your website in AWS, you first need to setup Stacy infrastructure under your AWS account. You must perform several steps before you can do it:

  1. Create the target S3 bucket. This is where your website will be published and from where it will be served (probably via CloudFront). Alternatively, you can use a bucket that you already have (Stacy also supports publishing in a subfolder in the target bucket).

  2. If you don't have it yet, create an S3 bucket that Stacy will use to upload the publisher Lambda function package. The publisher Lambda function is the piece that responds to Contentful publish and unpublish events and updates the relevant pages and assets in the target S3 bucket.

  3. Build the publisher package:

    stacy build-publisher

    This will create the publisher Lambda function package in your project under /build/stacy-mywebsite-publisher.zip. Upload this file to your Lambda functions S3 bucket.

Stacy's stacy new command has generated a CloudFormation template for the AWS environment and saved it in your project under /misc/cfn-template.json. You can review and customize it if necessary. Otherwise, go ahead and create Stacy stack for your website under your AWS account.

Once the CloudFormation stack is created, you need to adjust the target S3 bucket's policy to allow Stacy publisher publish generated website content in it. The bucket's policy can include something like the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "<Stacy publisher role ARN>"
            },
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::<bucket name>/*"
        }
    ]
}

In the above policy replace Stacy publisher role ARN with the value that you can find in your CloudFormation stack's PublisherRoleArn output parameter, and the bucket name with the target website bucket name (the bucket, to which the policy is applied).

Now you have to prepare your development environment for publishing. Open and edit .env file in your website project. In it, set all AWS_* variables to the correct values. Note, that you can find the value for AWS_PUBLISH_EVENT_SOURCE_MAPPING variable in the CloudFormation stack's PublishEventSourceMappingId output parameter.

Once your .env file is correctly setup, you can publish your website using:

stacy publish

One last setup step is to configure a webhook in your Contentful space to call Stacy publisher on publish and unpublish events. In your AWS account, in API Gateway service find the API created for you by Stacy. There is only one method POST /publish in the API's prod stage. Note its Invoke URL.

Also, go to the API Keys section and note the value of the API key created for Stacy.

In your Contentful space go to Space settings→Webhooks and add a webhook. Put the API Gatwey's invoke URL in the URL field (leave the method POST). Then pick Select specific triggering events option in the Triggers section. Check Publish and Unpublish checkboxes in Entry and Asset rows (4 checkboxes checked altogether).

In the Headers section click Add secret header. Put "X-API-Key" in the Key field and in the Value field put the API key from the API Gateway.

Once you save this webhook, publishing and unpulishing entries and assets in Contentful will trigger the publisher in the AWS setup and you are all set!