Git Product home page Git Product logo

gatsby-starter-silverstripe's Introduction

Gatsby Starter for Silverstripe CMS

This starter can be used for sites that source their data primarily from Silverstripe CMS.

Installation

$ gatsby new my-ss-project https://github.com/unclecheese/gatsby-starter-silverstripe

Dependencies

Getting started

You will need to install the following package on your Silverstripe site to expose your data to Gatsby:

$ composer require silverstripe/silverstripe-gatsby $ composer require sminnee/silverstripe-apikey

Once that is installed, ensure the __gatsby/graphql endpoing is working on your Silverstripe site. Generate an API key with ADMIN permissions to grab the site tree

Now, edit the gatsby-config.js file, and add the host of your Silverstripe backend to the options.host node in the plugin config.

    {
        resolve: `gatsby-source-silverstripe`,
        options: {
            host: `http://my-silverstripe-cms.local`,
            api_key: `SECRETAPIKEYSTRING`
        }
    },

Now, run gatsby develop. When the build is complete, you should have your entire site built out, with primary and secondary navigation, in a primitive template.

Features

This starter provides several features that aim to maintain a high level of parity between your Gatsby project and Silverstripe in order to ease migration pain and flatten the learning curve.

Automatic site tree generation

Any dataobject exposed by your Silverstripe backend that has a Link() method will get its own page in your Gatsby site, whether it's a SiteTree or DataObject.

By default, a templates/Layout/Page.js is provided, which should resolve all your SiteTree records.

Template selection

Template selection works the same way as Silverstripe.

Example

Template inventory:

src/
  templates/
    Page.js
    Layout/
      NewsPage.js
      Page.js
  • NewsPage extends Page => src/templates/Layout/NewsPage.js (match)
  • ContactPage extends Page => src/templates/Layout/Page.js (resolves to parent class)
  • StaffMember extends DataObject => NOT FOUND (Please create a Layout/StaffMember.js file)

Helper components

The starter ships with some basic components to help with common template needs. You're free to customise these as you see fit.

  • <MainNav />
  • <Breadcrumbs />
  • <SEOTags />

Forms

You can query forms as data, as they are provided by silverstripe/silverstripe-gatsby using the silverstripe-graphql-forms module. You will need to expose these forms to your GraphQL API on your Silverstripe site.

UncleCheese\GraphQLForms\FormQueryCreator:
  registered_forms:
    ## Expose a form that is generated by a method on a controller
    ContactForm: 'MyProject\Pages\ContactPageController.ContactForm'
    ## Expose a UserDefinedForm by ID
    MyUserDefinedForm: 45

Then, you can extract the form data using helpers, and render the form out with a library like formik.

import React from 'react';
import { extractFormData } from 'silverstripe-gatsby-helpers';

const MyFormPage = ({ data: { silverStripeDataObject, silverStripeForm } }) => {
  const { title, content } = silverStripeDataObject.SilverStripeSiteTree;
  const {
    initialValues,
    fields,
    actions,
    validator,
    attributes
  } = extractFormData(silverStripeForm);

  // Render form
};

See full example below.

Elemental support

Coming soon.

Example code

Primary navigation

import React from 'react';
import classnames from 'classnames';
import { getMenu } from 'silverstripe-gatsby-helpers';
import { Link } from 'gatsby';


const MainNav = () => {
    const menuItems = getMenu(1);
    return (
        <nav className="mainNav">
            <ul>
            {menuItems.map(item => (
                <li key={item.id} className={classnames({
                    current: item.isCurrent,
                    section: item.isSection,
                })}>
                    <Link to={item.link}>
                        {item.SilverStripeSiteTree.menuTitle}
                    </Link>
                </li>
            ))}
            </ul>
        </nav>
    );
};

Subnavigation

  import React from 'react';
  import { getChildren, isLevel } from 'silverstripe-gatsby-helpers';

  const children = getChildren();
  const isLevel2 = isLevel(2);
  const hasSubnav = isLevel(2) || !!children.length;
  const navItems = isLevel2 ? getMenu(2) : children;

  const MyPage = () => (
    <div>
    {hasSubnav &&
      <div className="sidebar">
        <h2>In this section</h2>
        <ul>
        {navItems.map(child => (
          <li key={child.id} className={classnames({
            current: child.isCurrent,
          })}>
          <Link to={child.link}>{child.SilverStripeSiteTree.title}</Link>
          </li>
        ))}
        </ul>
      </div>
      }
    </div>
  );

Form Example (Formik)

import React from 'react';
import { graphql } from 'gatsby';
import { Formik, Form, Field } from 'formik';
import { extractFormData, SSFieldHolder } from 'silverstripe-gatsby-helpers';

const renderField = fieldNode => {
    const { Component } = fieldNode;
    return (
        <SSFieldHolder key={fieldNode.formFieldID} fieldNode={fieldNode}>
            <Field component={Component} />
        </SSFieldHolder>
    )
};

const MyFormPage = ({ data: { silverStripeForm } }) => {
    const {
        initialValues,
        fields,
        actions,
        validator,
        attributes
    } = extractFormData(silverStripeForm);



    return (
    <div>
        <h2>Form</h2>
        <Formik
            initialValues={initialValues}
            validate={validator}
            onSubmit={(values, { setSubmitting }) => {
                setTimeout(() => {
                alert(JSON.stringify(values, null, 2));
                setSubmitting(false);
                }, 400);
            }}
        >
        {formik => (
            <Form {...attributes}>
                <fieldset>
                {fields.map(renderField)}
                {actions.length > 0 &&
                    <div className="btn-toolbar">
                        {actions.map(action => (
                            <button key={action.formFieldID} type="submit" name={action.name} id={action.formFieldID}>
                                {action.title}
                            </button>
                        ))}
                    </div>
                }
                </fieldset>
            </Form>
        )}
        </Formik>
    </div>
    );
};

export const pageQuery = graphql`
    query($link: String!) {
        silverStripeForm(formName: { eq: "ContactForm" }) {
            attributes {
                name
                value
            }
            formFields {
              ...SilverStripeFormFieldsFields
              attributes {
                  name
                  value
              }
            }
            formActions {
              ...SilverStripeFormFieldsFields
                attributes {
                    name
                    value
                }
            }
        }
    }
`;

export default MyFormPage;

For more information, see the silverstripe-gatsby-helpers package.

Magic

This starter adds some hooks to your gatsby-node.js file to inject global state that is used by most of the helper functions in silverstripe-gatsby-helpers. (See: SiteTreeProvider). Due to the nature of Gatsby's useStaticQuery, this code has to be colocated with your project. It is not recommended that you edit it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.