Add-Ons

Manage CSS from MODX

cssSweet

I'm using a modification of cssSweet to manage the site's CSS, based on Donald Atkinson's RO.IDEs concept of using MDOX resources as a development environment.

Stylesheet Context resources

  1. Install Ace editor
  2. Create a Stylesheet template (for TVs as CSS variables) - should be empty.
  3. Create a Context "stylesheet" with these context settings
    default_content_type (site) - 4 (text/css)
    default_template (site) - ?
    publish_default (site) - Yes
    search_default (site) - No (need to set specifically to No)
    cache_default (site) - No (need to set specifically to No)
    richtext_default (manager) - No (need to set specifically to No)
    
  4. Set up ClientConfig with a few categories
  5. Install and configure cssSweet - create a new saveContextCSS plugin, using the OnDocFormSave system event, and with these properties:
    csss.context_key (stylesheet)
    csss.custom_css_filename (style.css)
    csss.custom_css_path ([[++assets_path]]theme/themename/css/ - to use [[++assets_path]] check the "Pre-process tags in Property Values" box)
    csss.minify_custom_css (yes)
    csss.strip_css_comment_blocks (yes)
    Pre-process tags in Property Values - checked
    

Plugin saveContextCss

<?php
/**
 * saveContextCss
 * based on
 * saveCustomCss
 *
 * Copyright 2013 by YJ Tso <yj@modx.com>
 *
 * saveCustomCss and cssSweet is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * saveCustomCss and cssSweet is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * saveCustomCss and cssSweet; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package cssSweet
 * 
 * MODIFIED June 2014 by sottwell
 * uses different triggering event, uses pdoResources internally - no need for a chunk.
 * Event: OnDocFormSave
 * Properties:
 *    csss.context_key
 *    csss.custom_css_filename
 *    csss.custom_css_path
 *    csss.minify_custom_css
 *    csss.strip_css_comment_blocks
 *
 * Checks resource's content_type - 4, "text/css"
 * Checks resource's context_key - default "stylesheet"
 *
 * TO DO: change file_exists check on line 60 to is_dir. Better check on last line OR more accurate return notice.
 **/
 
// get contextKey - "stylesheet" by default
$csssContextKey = $modx->getOption('csss.context_key',$scriptProperties,$modx->getOption('css.contextKey',null,'stylesheet'));

$csssContentType = 4; // text/css
$contextKey = $resource->get('context_key');
$contentType = $resource->get('context_type');

if(($contextKey == $csssContextKey) && ($contentType == $cssscontentType)) {

    // Optionally a file name can be specified in plugin properties
  $filename = $modx->getOption('csss.custom_css_filename',$scriptProperties,$modx->getOption('csss.custom_css_filename',null,'csss-custom.css'));

    // Optionally minify the output, defaults to 'true'
  $minify_custom_css = $modx->getOption('csss.minify_custom_css',$scriptProperties,$modx->getOption('csss.minify_custom_css',null,true));
    // strips CSS comment blocks, defaults to 'false'
  $strip_comments = $modx->getOption('csss.strip_css_comment_blocks',$scriptProperties,$modx->getOption('csss.strip_css_comment_blocks',null,false));

    // Construct path from system settings - can be set in properties as of v.1.1
  $csssCustomCssPath = $modx->getOption('csss.custom_css_path',$scriptProperties,$modx->getOption('csss.custom_css_path'));
  if ( !$csssCustomCssPath ) {
    $assetsPath = $modx->getOption('assets_path');
    $csssCustomCssPath = $assetsPath . 'components/csssweet/';
    $modx->log(modX::LOG_LEVEL_INFO, 'csss.custom_css_path was not defined. Path set to ' . $csssCustomCssPath,'','saveCustomCss');
  }

    // Grab the ClientConfig class
  $ccPath = $modx->getOption('clientconfig.core_path', null, $modx->getOption('core_path') . 'components/clientconfig/');
  $ccPath .= 'model/clientconfig/';
  if (file_exists($ccPath . 'clientconfig.class.php')) $clientConfig = $modx->getService('clientconfig','ClientConfig', $ccPath);
  $settings = array();

    // If we got the class (which means it's installed properly), include the settings
  if ($clientConfig instanceof ClientConfig) {
    $settings = $clientConfig->getSettings();
      /* Make settings available as [[++tags]] */
    $modx->setPlaceholders($settings, '+');
  } else { 
    $modx->log(modX::LOG_LEVEL_WARN, 'Failed to load ClientConfig class. ClientConfig settings not included.','','saveCustomCssClientConfig'); 
  }

    // If directory exists but isn't writable we have a problem, Houston
  if ( file_exists($csssCustomCssPath) && !is_writable($csssCustomCssPath) ) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'The directory at ' . $csssCustomCssPath . 'is not writable!','','saveCustomCss');
    return;
  }
    
    // Check if directory exists, if not, create it
  if ( !file_exists($csssCustomCssPath) ) {
    mkdir($csssCustomCssPath,0755,true);
    $modx->log(modX::LOG_LEVEL_INFO, 'Directory created at ' . $csssCustomCssPath,'','saveCustomCss');
  }

    // Parse chunk with $settings array
  $props = array(
                 'context' => $csssContextKey,
                 'parents' => '0',
                 'includeContent' => '1',
                 'sortby' => 'menuindex',
                 'sortdir' => 'ASC',
                 'tpl' => '@CODE [[+content]]'
                );
  $contents = $modx->runSnippet('pdoResources', $props);

    // Define target file
  $file = $csssCustomCssPath . $filename;

    // Output
  if ($minify_custom_css) {
    $contents = preg_replace("/\s+/", " ", $contents);
    $expanded = array(' {', '{ ', ' }', '} ', ' :', ': ', ' ;', '; ', ', ', ' ,');
    $contracted = array('{', '{', '}', '}', ':', ':', ';', ';', ',', ',');
    $contents = str_replace($expanded, $contracted, $contents);
    if ($strip_comments) {
      $contents = preg_replace("/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//", " ", $contents);
    }
  } 
  file_put_contents($file,$contents);
  if (file_exists($file) && is_readable($file)) $modx->log(modX::LOG_LEVEL_INFO, 'Success! Custom CSS saved to file "' . $file . '"','','saveCustomCss');
}
Susan Ottwell
December 2015