Skip to content

Instantly share code, notes, and snippets.

@sottwell
Last active February 2, 2016 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sottwell/2582687f32c6a19d1ec6 to your computer and use it in GitHub Desktop.
Save sottwell/2582687f32c6a19d1ec6 to your computer and use it in GitHub Desktop.
saveContextCss Plugin to replace CssSweet's chunk-based saveCustomCss plugin - MODX Revolution
<?php
/**
* saveCustomCss
* @author @sepiariver
* Copyright 2013 - 2015 by YJ Tso <yj@modx.com> <info@sepiariver.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 1 Feb 2016 by sottwell <sottwell@sottwell.com>
*
* SaveContextCss
*
* Uses resources in a context, 'stylesheet' by default
* Uses pdoMenu to aggregate the resources content
* Uses OnDocFormSave event
* New Property, 'cssc.context_key' with the default of 'stylesheet'
*/
// In case the wrong event is enabled in plugin properties
if ($modx->event->name !== 'OnDocFormSave') return;
// get contextKey - "stylesheet" by default
$csscContextKey = $modx->getOption('cssc.context_key', $scriptProperties, 'stylesheet');
//$modx->log(modX::LOG_LEVEL_ERROR, 'Context Key = ' . $csscContextKey, '', 'saveContextCss');
$csscContentType = 4; // text/css
$contextKey = $resource->get('context_key');
$contentType = $resource->get('content_type');
if(($contextKey != $csscContextKey) && ($contentType != $csscContentType)) {
//$modx->log(modX::LOG_LEVEL_ERROR, 'Context Key or Content Type mismatch', '', 'saveContextCss');
return;
}
// Grab the cssSweet class
$csssweet = null;
$cssSweetPath = $modx->getOption('csssweet.core_path', null, $modx->getOption('core_path') . 'components/csssweet/');
$cssSweetPath .= 'model/csssweet/';
if (file_exists($cssSweetPath . 'csssweet.class.php')) $csssweet = $modx->getService('csssweet', 'CssSweet', $cssSweetPath);
if (!$csssweet || !($csssweet instanceof CssSweet)) {
$modx->log(modX::LOG_LEVEL_ERROR, '[SaveCustomCss] could not load the required csssweet class!');
return;
}
// Dev mode option
$mode = ($modx->getOption('dev_mode', $scriptProperties, 0)) ? 'dev' : 'custom';
// Letting folks know what's going on
$modx->log(modX::LOG_LEVEL_INFO, 'saveCustomCss plugin is running in mode: ' . $mode);
// Specify an output file name in plugin properties
$filename = $modx->getOption($mode . '_css_filename', $scriptProperties, '');
if (empty($filename)) return;
// Optionally choose an output format if not minified
$css_output_format = $modx->getOption('css_output_format', $scriptProperties, 'Expanded');
$css_output_format_options = array('Expanded','Nested','Compact');
if (!in_array($css_output_format, $css_output_format_options)) $css_output_format = 'Expanded';
// Optionally minify the output, defaults to 'true'
$minify_custom_css = (bool) $modx->getOption('minify_custom_css', $scriptProperties, true);
$css_output_format = ($minify_custom_css) ? 'Compressed' : $css_output_format;
// Strip CSS comment blocks; defaults to 'false'
$strip_comments = (bool) $modx->getOption('strip_css_comment_blocks', $scriptProperties, false);
$css_output_format = ($minify_custom_css && $strip_comments) ? 'Crunched' : $css_output_format;
// Optionally set base_path for scss imports
$scss_import_paths = $modx->getOption('scss_import_paths', $scriptProperties, '');
$scss_import_paths = (empty($scss_import_paths)) ? array() : $csssweet->explodeAndClean($scss_import_paths);
// Get the output path; construct fallback; log for debugging
$csssCustomCssPath = $modx->getOption('custom_css_path', $scriptProperties, '');
if (empty($csssCustomCssPath)) $csssCustomCssPath = $modx->getOption('assets_path') . 'components/csssweet/';
$modx->log(modX::LOG_LEVEL_ERROR, '$csssCustomCssPath is: ' . $csssCustomCssPath . ' on line: ' . __LINE__);
$csssCustomCssPath = rtrim($csssCustomCssPath, '/') . '/';
// 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)) {
if (mkdir($csssCustomCssPath, 0755, true)) {
$modx->log(modX::LOG_LEVEL_INFO, 'Directory created at ' . $csssCustomCssPath, '', 'saveCustomCss');
} else {
$modx->log(modX::LOG_LEVEL_ERROR, 'Directory could not be created at ' . $csssCustomCssPath, '', 'saveCustomCss');
return;
}
}
// Initialize settings array
$settings = array();
// Get context settings
$settings_ctx = $modx->getOption($mode . '_context_settings_context', $scriptProperties, '');
if (!empty($settings_ctx)) {
$settings_ctx = $modx->getContext($settings_ctx);
if ($settings_ctx && is_array($settings_ctx->config)) $settings = array_merge($settings, $settings_ctx->config);
}
// Attempt to get Client Config settigs
$settings = $csssweet->getClientConfigSettings($settings);
/* Make settings available as [[++tags]] */
$modx->setPlaceholders($settings, '+');
// fetch the CSS resources
$contents = '';
$props = array(
'context' => $csscContextKey,
'parents' => '0',
'outerTpl' => '@CODE [[+wrapper]]',
'tpl' => '@CODE [[+content]][[+wrapper]]'
);
$contents = $modx->runSnippet('pdoMenu', $props);
// If there's no result, what's the point?
if (empty($contents)) return;
// CSS comments
$contents = '/* Contents generated by MODX - this file will be overwritten. */' . PHP_EOL . $contents;
// The scssphp parser keeps comments with !
if (!$strip_comments) $contents = str_replace('/*', '/*!', $contents);
// Define target file
$file = $csssCustomCssPath . $filename;
// Init scssphp
$scssMin = $csssweet->scssphpInit($scss_import_paths, $css_output_format);
if ($scssMin) {
try {
$contents = $scssMin->compile($contents);
}
catch (Exception $e) {
$modx->log(modX::LOG_LEVEL_ERROR, $e->getMessage() . ' scss not compiled. minification not performed.','','saveCustomCss');
}
} else {
$modx->log(modX::LOG_LEVEL_ERROR, 'Failed to load scss class. scss not compiled. minification not performed.','','saveCustomCss');
}
// If we failed scss and minification at least output what we have
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');
@sottwell
Copy link
Author

This is a plugin to use in place of the supplied cssSweet saveCustomCss plugin. Insead of chunks, it uses resources in a specified context. Otherwise, it works much the same, aggregating the resources' content, minifying the resulting CSS, and writing it to file.

@sottwell
Copy link
Author

sottwell commented Feb 1, 2016

Add a new Property, 'cssc.context_key' with a default of "stylesheet".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment