Skip to content

Anatomy of a plugin

Brian Rinaldi edited this page Mar 27, 2020 · 3 revisions

For a complete step-by-step guide to building a Sourcebit plugin, check out our tutorial at: https://www.stackbit.com/blog/sourcebit-plugin/

Imagine an assembly line with different conveyor belts. Throughout the length of the assembly line are factory workers, who can place, remove and modify items from any of the conveyor belts. Workers can even terminate any of the existing conveyor belts or start new ones, if they want.

That assembly line is Sourcebit. The conveyor belts are data buckets and the factory workers are plugins.

Diagram of data flow between plugins

Core data buckets

Even though plugins can create new data buckets with names of their choice, there are currently three special data buckets that must not be removed and whose format must be respected.

Example: Contentful + Jekyll

Let's look at an example Sourcebit configuration using a source plugin that pulls content from Contentful (sourcebit-source-contentful), and a target plugin that writes files to disk in a format that Jekyll expects (sourcebit-target-jekyll).

✏️ Example configuration file
module.exports = {
  plugins: [
    {
      module: require("sourcebit-source-contentful"),
      options: {
        accessToken: process.env["CONTENTFUL_ACCESS_TOKEN"],
        environment: "master",
        spaceId: "1q2w3e4r"
      }
    },
    {
      module: require("sourcebit-target-jekyll"),
      options: {
        writeFile: function(entry, utils) {
          const { __metadata: meta, ...fields } = entry;

          if (!meta) return;

          const { createdAt = "", modelName, projectId, source } = meta;

          if (
            modelName === "post" &&
            projectId === "9jcrwqxlh8hv" &&
            source === "sourcebit-source-contentful"
          ) {
            const {
              __metadata,
              content: content,
              layout,
              ...frontmatterFields
            } = entry;

            return {
              content: {
                body: fields["content"],
                frontmatter: { ...frontmatterFields, layout: fields["layout"] }
              },
              format: "frontmatter-md",
              path:
                "_posts/" +
                createdAt.substring(0, 10) +
                "-" +
                utils.slugify(fields["title"]) +
                ".md"
            };
          }
        }
      }
    }
  ]
};

This is how data flows:

  1. sourcebit-source-contentful fetches content types and entries from Contentful and place them on the models and objects data buckets, respectively.
  2. sourcebit-target-jekyll reads from the objects bucket and, for each object that should generate a file on disk, it places an object in the files data bucket. This object indicates the content, format and location of the file to be created (see Writing files to disk). When using the interactive setup process, the plugin also reads from the models bucket in order to list all the content types and ask the user what to do with each of them.
  3. Finally, the core application will read from the files bucket and create a file for each item.

If Sourcebit was executed in watch mode (using the --watch CLI parameter or with watch: true option), the entire process will start again whenever sourcebit-source-contentful detects a content update.

Clone this wiki locally