Search code examples
phpcsssilverstripe

Changing / setting CSS from a CMS value in Silverstripe 5


Is there a way to create a field for the user to fill a property value within the CMS admin panel, and have it change the publicly viewable document?

For example, setting a colour value for a color palette. I looked into the WYSIWYG styles, but as far as I understand, they're for changing the styles of the Admin panel itself? Rather than allowing the modification of styles from the Admin panel?

I've tried to create Varchar fields to hold this value, but I can't seem to get Silverstripe to populate it.

        'PrimaryColour' => 'Varchar',
        'AccentColour1' => 'Varchar',
        'AccentColour2' => 'Varchar',
        $fields->addFieldsToTab('Root.Colours', array (
            TextField::create('PrimaryColour','Primary Colour'),
            TextField::create('AccentColour1','Accent Colour 1'),
            TextField::create('AccentColour2','Accent Colour 2'),
        ));

I've assumed that Silverstripe won't try to fill in PHP values within the CSS file, so I tried creating a style tag in the .SS file, and referencing them there

    <style>
    body {
        --primary: $PrimaryColour;
        --accent1: $AccentColour1;
        --accent2: $AccentColour2;
    }
    </style>

I'm setting CSS variables here so that I can refer to it elsewhere in the CSS


Solution

  • The code you supplied works fine for me in a fresh installation of silverstripe/installer - just in case there's something in the wrong place, I've copied my full code here to show it in context.

    <?php
    // app/src/Page.php
    
    namespace {
    
        use SilverStripe\CMS\Model\SiteTree;
        use SilverStripe\Forms\TextField;
    
        class Page extends SiteTree
        {
            private static $db = [
                'PrimaryColour' => 'Varchar',
                'AccentColour1' => 'Varchar',
                'AccentColour2' => 'Varchar',
            ];
    
            public function getCMSFields()
            {
                $fields = parent::getCMSFields();
                $fields->addFieldsToTab('Root.Colours', [
                    TextField::create('PrimaryColour','Primary Colour'),
                    TextField::create('AccentColour1','Accent Colour 1'),
                    TextField::create('AccentColour2','Accent Colour 2'),
                ]);
                return $fields;
            }
        }
    }
    
    <!-- themes/my-theme/templates/Page.ss -->
    
    <html>
    <head>
        <!-- ... -->
        <style>
        body {
            --primary: $PrimaryColour;
            --accent1: $AccentColour1;
            --accent2: $AccentColour2;
        }
        </style>
    </head>
    <!-- ... -->
    </html>
    

    Try this in a fresh installation, and if it works, then it's clear that you've either got something really simple wrong in your project (e.g. putting the style tag in the wrong template), or some customisation is getting in the way (e.g. CSP blocking inline style tags)

    In addition to that, instead of a regular text field, you might want to try a colour picker such as tractorcow/silverstripe-colorpicker