The purpose of this module is to allow Silverstripe CMS developers to quickly get started building React components to customise the CMS UI.
This guides assumes you have the following:
- a working Silverstripe CMS project
- the
composerexecutable installed in your path - the
yarnexecutable installed in your path
composer require maxime-rainville/recipe-reactInstalling the recipe will:
- Add a
app/cms-clientfolder to your project. This is where you will put your React JS components. - Add a
app/_config/recipe-config.ymlfile to your project. This will get your compiled JS/CSS code loaded in the Silverstripe CMS admin.
To compile app/cms-client, you need to install silverstripe/admin from source and download the silverstripe/admin JS dependencies.
maxime-rainville/recipe-react comes with a small bash script to simplyfie this process:
- Running
vendor/bin/from-source checkwill validate ifsilverstripe/adminhas been installed properly to do CMS JS development. - Running
vendor/bin/from-source reinstallwill attempt to reinstallsilverstripe/adminto allow you to compileapp/cms-client.
Alternatively, you can run this sequence of command:
# Start in your project root. This will reinstall admin from source
rm -rf vendor/silverstripe/admin
composer install --prefer-source
# This line will download all silverstripe/admin JS dependencies
(cd vendor/silverstripe/admin && yarn install)You should now be able to compile your CMS client:
cd app/cms-client
yarn install
yarn devThis should create a app/cms-client/dist directory.
The app/cms-client/dist folder needs to be accessible to your browser. To do this you need to "expose" it.
Update your project composer.json file. You need to add an expose key under extra and give it an array of paths to expose. Your composer file should look something like this when you are done.
{
"name": "your/project",
"require": {
"php": "^7.1 || ^8",
"silverstripe/recipe-plugin": "^1.2",
"silverstripe/recipe-cms": "4.x-dev",
"silverstripe-themes/simple": "~3.2.0",
"maxime-rainville/recipe-react": "dev-master"
},
"extra": {
"resources-dir": "_resources",
"expose": [
"app/cms-client/dist"
]
},
}You now need to run this command to expose your cms-client:
composer vendor-exposeYou should now have a folder public/_resources/app/cms-client/dist.
You can take these optional steps to validate that everything is working correctly.
- Edit
app/cms-client/src/bundles/bundle.jsand addalert('My set up is done');at the end. - Run
yarn devfromapp/cms-clientto rebuild your library. - Rebuild your Silverstripe CMS project with
vendor/bin/sake dev/build - Access your test site in your browser. You may need to flush the Silverstripe cache with by adding
?flush=1to your URL. - Access the CMS administration area.
You should see a JS alert with "My set up is done".
In this step we will create a simple On/Off form field.
In your PHP code base, create a OnOffButton.php file with this content. This will be the object you will be adding to your PHP form.
<?php
use MaximeRainville\SilverstripeReact\ReactFormField;
use SilverStripe\Forms\FormField;
class OnOffButton extends ReactFormField
{
/**
* This should match the value type that our field will manage
*/
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_STRING;
/**
* If your component renders an HTML form field, you can omit this line
*/
protected $renderInput = true;
/**
* This will be the name of the React component that will be use to
* render the field.
*/
public function getComponent(): string
{
return 'OnOffButton';
}
/**
* You can customise the props that will be pass to your React component
* by overriding the `ReactFormField::getProps` method
*/
public function getProps(): array
{
return parent::getProps();
}
/**
* Our field will default to `off`
*/
public function Value()
{
return parent::Value() ?: 'off';
}
}This is the react component will render our form field. Create a app/cms-client/src/components/OnOffButton.js file with the following content.
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import Button from 'components/Button/Button';
export default function ({ value, extraClass, id, onChange }) {
const props = {
color: 'info',
className: extraClass,
outline: value === 'off',
// This callback will tell our parent when our form value changes
onClick: (event) => {
onChange(event, { id, value: value === 'off' ? 'on' : 'off' });
}
};
return <Button {...props}>{value}</Button>;
}We need to register our new component our form field can be bootstrapped properly.
Update app/cms-client/src/components/index.js with this content.
import OnOffButton from './OnOffButton';
export {
OnOffButton
};We need to rebuild our CMS client with yarn dev.
You can add your new form field to any CMS form with this code snippet.
$fields->addFieldToTab(
'Root.Main',
OnOffButton::create('Toggle')
);Simply rebuild your project with vendor/bin/sake dev/build and access your CMS form to view the result.