├── .gitattributes ├── .gitignore ├── default ├── templates │ ├── bowerrc │ ├── travis.yml │ ├── _logo.png │ ├── _screenshot.png │ ├── _package.json │ ├── d8 │ │ ├── _theme.theme │ │ └── _theme.info.yml │ ├── _style.scss │ ├── _editor.scss │ ├── __config.scss │ ├── _bower.json │ ├── _style.css │ ├── _editor.css │ ├── _javascript.js │ ├── d7 │ │ ├── templates │ │ │ ├── region.tpl.php │ │ │ ├── block--no-wrapper.tpl.php │ │ │ ├── block--navigation.tpl.php │ │ │ ├── block.tpl.php │ │ │ ├── comment-wrapper.tpl.php │ │ │ ├── node.tpl.php │ │ │ ├── comment.tpl.php │ │ │ ├── html.tpl.php │ │ │ └── page.tpl.php │ │ ├── _theme.info │ │ └── _template.php │ └── _config.rb └── index.js ├── .travis.yml ├── .editorconfig ├── common ├── templates │ ├── editorconfig │ └── jshintrc ├── index.js └── drupal-logo.js ├── test ├── test-load.js └── test-creation.js ├── .jshintrc ├── LICENSE ├── package.json ├── README.md └── app └── index.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | temp/ 3 | -------------------------------------------------------------------------------- /default/templates/bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "libraries" 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.8' 4 | - '0.10' 5 | -------------------------------------------------------------------------------- /default/templates/travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.8' 4 | - '0.10' 5 | -------------------------------------------------------------------------------- /default/templates/_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelmord/generator-drupaltheme/HEAD/default/templates/_logo.png -------------------------------------------------------------------------------- /default/templates/_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelmord/generator-drupaltheme/HEAD/default/templates/_screenshot.png -------------------------------------------------------------------------------- /default/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= packageInfo.name %>", 3 | "version": "<%= packageInfo.version %>", 4 | "dependencies": {} 5 | } 6 | -------------------------------------------------------------------------------- /default/templates/d8/_theme.theme: -------------------------------------------------------------------------------- 1 | theme. 6 | */ 7 | use Drupal\Core\Template\RenderWrapper; 8 | -------------------------------------------------------------------------------- /default/templates/_style.scss: -------------------------------------------------------------------------------- 1 | /* 2 | // Main stylesheet containing layout, features and style overrides 3 | // ========================================================================== */ 4 | 5 | @import 'config'; 6 | -------------------------------------------------------------------------------- /default/templates/_editor.scss: -------------------------------------------------------------------------------- 1 | /* 2 | // Stylesheet for reset, typography and all elements to be shown or used in wysiwyg 3 | // ========================================================================== */ 4 | 5 | @import 'config'; 6 | -------------------------------------------------------------------------------- /default/templates/d8/_theme.info.yml: -------------------------------------------------------------------------------- 1 | name: <%= themeName %> 2 | type: theme 3 | description: <%= themeDesc %> 4 | version: VERSION 5 | core: 8.x 6 | stylesheets: 7 | all: 8 | - css/editor.css 9 | - css/style.css 10 | # stylesheets-remove: 11 | # - normalize.css 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /common/templates/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /test/test-load.js: -------------------------------------------------------------------------------- 1 | /*global describe, beforeEach, it*/ 2 | 'use strict'; 3 | 4 | var assert = require('assert'); 5 | 6 | describe('drupaltheme generator', function () { 7 | it('can be imported without blowing up', function () { 8 | var app = require('../app'); 9 | assert(app !== undefined); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /default/templates/__config.scss: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // @file: 3 | // VARIABLES for SASS/COMPASS 4 | // ============================================================================= 5 | 6 | <% if (styleCOMPASS || compassBootstrap || frondly) { %>@import 'compass';<% } %> 7 | -------------------------------------------------------------------------------- /default/templates/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= themeName %>", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "html5shiv": "~3.6.2"<% if (compassBootstrap) { %>, 6 | "bootstrap-sass-official": "~3.1.1"<% } %><% if (frondly) { %>, 7 | "frondly": "https://github.com/pixelmord/frondly.git"<% } %> 8 | }, 9 | "devDependencies": {} 10 | } 11 | -------------------------------------------------------------------------------- /default/templates/_style.css: -------------------------------------------------------------------------------- 1 | /* 2 | // Main stylesheet containing layout, features and style overrides 3 | // ========================================================================== */ 4 | 5 | <% if (styleCOMPASS || compassBootstrap || frondly) { %> 6 | /* 7 | // a SASS/COMPASS file 'styles.scss' is in the sass directory 8 | // and upon first compilation this file here will be overridden 9 | */ 10 | <% } %> 11 | -------------------------------------------------------------------------------- /default/templates/_editor.css: -------------------------------------------------------------------------------- 1 | /* 2 | // Stylesheet for reset, typography and all elements to be shown or used in wysiwyg 3 | // ========================================================================== */ 4 | 5 | <% if (styleCOMPASS || compassBootstrap || frondly) { %> 6 | /* 7 | // a SASS/COMPASS file 'editor.scss' is in the sass directory 8 | // and upon first compilation this file here will be overridden 9 | */ 10 | <% } %> 11 | -------------------------------------------------------------------------------- /default/templates/_javascript.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | 'use strict'; 3 | Drupal.behaviors.<%= themeMachineName %> = { 4 | attach: function (context, settings) { 5 | // This is an example for the use of a behaviour 6 | // @see: https://drupal.org/node/756722 7 | // $('body', context).click(function () { 8 | // console.log('Hello world!') 9 | // }); 10 | } 11 | }; 12 | 13 | })(jQuery); 14 | -------------------------------------------------------------------------------- /default/templates/d7/templates/region.tpl.php: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "es5": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 4, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "white": true 22 | } 23 | -------------------------------------------------------------------------------- /common/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var path = require('path'); 4 | var yeoman = require('yeoman-generator'); 5 | 6 | 7 | var CommonGenerator = module.exports = function CommonGenerator(args, options, config) { 8 | yeoman.generators.Base.apply(this, arguments); 9 | 10 | }; 11 | 12 | util.inherits(CommonGenerator, yeoman.generators.Base); 13 | 14 | CommonGenerator.prototype.app = function app() { 15 | // common templates 16 | this.copy('editorconfig', '.editorconfig'); 17 | this.copy('jshintrc', '.jshintrc'); 18 | }; 19 | -------------------------------------------------------------------------------- /common/templates/jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "bitwise": true, 4 | "camelcase": true, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "es3": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "regexp": true, 15 | "undef": true, 16 | "unused": true, 17 | "strict": true, 18 | "globalstrict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "white": true, 22 | "jquery": true, 23 | "predef": [ 24 | "Drupal", 25 | "CKEDITOR" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /default/templates/d7/templates/block--no-wrapper.tpl.php: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | 18 | > 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /default/templates/d7/_theme.info: -------------------------------------------------------------------------------- 1 | name = <%= themeName %> 2 | description = <%= themeDesc %> 3 | core = 7.x 4 | 5 | ;-------------------- C S S ----------------------- 6 | ; We include one "editor" stylesheet that contains 7 | ; resets and normalizations as well as styles used 8 | ; by editors such as typography and styles for use 9 | ; in a WYSIWYG editor. 10 | ; 11 | ; All other styles will be placed in the styles 12 | ; file. This will include styles for layout, page 13 | ; elements, features and print overrides. 14 | 15 | stylesheets[all][] = css/editor.css 16 | stylesheets[all][] = css/style.css 17 | 18 | ;--------------------- J S ------------------------ 19 | 20 | scripts[] = js/<%= themeMachineName %>.js 21 | -------------------------------------------------------------------------------- /default/templates/d7/templates/block--navigation.tpl.php: -------------------------------------------------------------------------------- 1 | 17 | 28 | -------------------------------------------------------------------------------- /default/templates/d7/templates/block.tpl.php: -------------------------------------------------------------------------------- 1 | 18 |
> 19 | 20 | 21 | 22 | > 23 | 24 | 25 | 26 | 27 | 28 |
29 | -------------------------------------------------------------------------------- /default/templates/d7/templates/comment-wrapper.tpl.php: -------------------------------------------------------------------------------- 1 | 14 |
> 15 | type != 'forum'): ?> 16 | 17 |

18 | 19 | 20 | 21 | 22 | 23 | 24 |

25 | 26 | 27 |
28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Andreas Sahle 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-drupaltheme", 3 | "version": "0.1.1", 4 | "description": "A generator for Yeoman scaffolding a Drupal theme", 5 | "keywords": [ 6 | "yeoman-generator", 7 | "Drupal", 8 | "Drush", 9 | "theme", 10 | "frontend" 11 | ], 12 | "homepage": "https://github.com/pixelmord/generator-drupaltheme", 13 | "bugs": "https://github.com/pixelmord/generator-drupaltheme/issues", 14 | "author": { 15 | "name": "Andreas Sahle", 16 | "email": "", 17 | "url": "https://github.com/pixelmord" 18 | }, 19 | "main": "app/index.js", 20 | "repository": { 21 | "type": "git", 22 | "url": "git://github.com/pixelmord/generator-drupaltheme.git" 23 | }, 24 | "scripts": { 25 | "test": "mocha" 26 | }, 27 | "dependencies": { 28 | "yeoman-generator": "~0.13.4", 29 | "lodash": "~1.3.1", 30 | "underscore.string": "~2.3.3", 31 | "chalk": "~0.3.0" 32 | }, 33 | "devDependencies": { 34 | "mocha": "~1.14.0" 35 | }, 36 | "engines": { 37 | "node": ">=0.8.0" 38 | }, 39 | "licenses": [ 40 | { 41 | "type": "GPL" 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /default/templates/d7/templates/node.tpl.php: -------------------------------------------------------------------------------- 1 | 16 |
role="article"> 17 | 18 | 19 | 20 | > 21 | 22 | 23 | 24 | 25 |

26 | 27 | 28 | 29 |
30 | 31 | 32 |
33 | 34 | 35 | 41 | 42 | 43 |
44 | -------------------------------------------------------------------------------- /default/templates/d7/templates/comment.tpl.php: -------------------------------------------------------------------------------- 1 | 17 |
> 18 | 19 |
20 | 25 | 26 | 27 | 28 | > 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |

41 | 42 |
43 | 44 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 56 | 57 |
58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generator-drupaltheme 2 | [![Build Status](https://secure.travis-ci.org/pixelmord/generator-drupaltheme.png?branch=master)](https://travis-ci.org/pixelmord/generator-drupaltheme) 3 | 4 | A generator for Yeoman. 5 | (!Important! This is work in progress right now, so keep calm and describe your issues in the queue on github) 6 | 7 | ## Getting started 8 | - Make sure you have [yo](https://github.com/yeoman/yo) installed: 9 | `npm install -g yo` 10 | - Install the generator: `npm install -g generator-drupaltheme` 11 | - Run: `yo drupaltheme` 12 | 13 | ## Current functionality includes: 14 | - info file 15 | - placeholder images for logo and screenshot 16 | - bower, editor and jshint config 17 | - choice of CSS, SCSS or COMPASS scaffolding 18 | - HTML5 templates and preprocessing 19 | 20 | ### NEW: drush integration 21 | 22 | There is currently an experimental drush integration through a drush plugin. 23 | See the sandbox project on drupal.org: 24 | [drush themegenerator](http://drupal.org/sandbox/hydra/2143001) 25 | 26 | It currently provides a 27 | - drush command (drush gt) to 28 | - pass Drupal environment variables to yeoman 29 | - pick up yo generator configuration from (base)themes 30 | - pick up yo generator configuration from ~/.drush_themegenerator/starterkits folder 31 | 32 | A sample yo generator configuration can be found here: 33 | [gt_blueprints](https://github.com/wunderkraut/gt_blueprints) 34 | 35 | ```bash 36 | $ mkdir ~/.drush_themegenerator/ 37 | $ cd ~/.drush_themegenerator/ 38 | $ git clone https://github.com/wunderkraut/gt_blueprints starterkits 39 | ``` 40 | 41 | 42 | ## Roadmap 43 | 44 | ### Common 45 | - directory structure documentation 46 | - Grunt integration 47 | - linting 48 | - compiling 49 | - uglyfying 50 | - optimization 51 | - live reloading 52 | 53 | 54 | ### Drupal 7 55 | - more preprocessing with (sane) defaults 56 | - better template.php structure with includes 57 | - sub generator for panels/panelizer 58 | 59 | ### Drupal 8 60 | - a choice for Drupal 8 flavor 61 | 62 | ## License 63 | [GPL License](http://www.gnu.org/licenses/gpl) 64 | -------------------------------------------------------------------------------- /default/templates/_config.rb: -------------------------------------------------------------------------------- 1 | # 2 | # This file is only needed for Compass/Sass integration. If you are not using 3 | # Compass, you may safely ignore or delete this file. 4 | # 5 | # If you'd like to learn more about Sass and Compass, see the sass/README.txt 6 | # file for more information. 7 | # 8 | 9 | 10 | # Change this to :production when ready to deploy the CSS to the live server. 11 | environment = :development 12 | #environment = :production 13 | 14 | # In development, we can turn on the FireSass-compatible debug_info. 15 | firesass = false 16 | #firesass = true 17 | 18 | 19 | # Location of the theme's resources. 20 | css_dir = "css" 21 | sass_dir = "sass" 22 | images_dir = "images" 23 | javascripts_dir = "js" 24 | 25 | 26 | # Require any additional compass plugins here. 27 | #require 'plugin' 28 | <% if (frondly) { %> 29 | # frondly would use susy plugin if you include one of the layout partials 30 | require 'susy' 31 | <% } %> 32 | # State additional import paths here. 33 | <% if (frondly) { %> 34 | # Add import path to frondly sass partials 35 | add_import_path "libraries/frondly/sass" 36 | <% } %> 37 | <% if (compassBootstrap) { %> 38 | # Add bootstrap-sass as import path to use components and mixins from there 39 | add_import_path "libraries/bootstrap-sass-official/vendor/assets/stylesheets/bootstrap" 40 | <% } %> 41 | ## 42 | ## You probably don't need to edit anything below this. 43 | ## 44 | 45 | # You can select your preferred output style here (can be overridden via the command line): 46 | # output_style = :expanded or :nested or :compact or :compressed 47 | output_style = (environment == :development) ? :expanded : :compressed 48 | 49 | # To enable relative paths to assets via compass helper functions. 50 | relative_assets = true 51 | 52 | # To disable debugging comments that display the original location of your selectors. Uncomment: 53 | line_comments = true 54 | 55 | # Pass options to sass. For development, we turn on the FireSass-compatible 56 | # debug_info if the firesass config variable above is true. 57 | sass_options = (environment == :development && firesass == true) ? {:debug_info => true} : {} 58 | -------------------------------------------------------------------------------- /default/templates/d7/templates/html.tpl.php: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | > 24 | 25 | 26 | <?php print $head_title; ?> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | 42 | > 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/test-creation.js: -------------------------------------------------------------------------------- 1 | /*global describe, beforeEach, it*/ 2 | 'use strict'; 3 | 4 | var path = require('path'); 5 | var helpers = require('yeoman-generator').test; 6 | 7 | 8 | describe('drupaltheme generator', function () { 9 | beforeEach(function (done) { 10 | var deps = [ 11 | '../../app', 12 | '../../common', 13 | '../../default' 14 | ]; 15 | helpers.testDirectory(path.join(__dirname, 'temp'), function (err) { 16 | if (err) { 17 | return done(err); 18 | } 19 | 20 | this.app = helpers.createGenerator('drupaltheme:app', deps); 21 | done(); 22 | }.bind(this)); 23 | }); 24 | 25 | it('creates expected files', function (done) { 26 | var expected = [ 27 | // add files you expect to exist here. 28 | ['bower.json', /"name": "testing-name"/], 29 | ['package.json', /"name": "testing-name"/], 30 | '.jshintrc', 31 | '.editorconfig', 32 | 'temp.info', 33 | 'css/editor.css', 34 | 'css/style.css', 35 | 'js/temp.js' 36 | ]; 37 | 38 | helpers.mockPrompt(this.app, { 39 | 'themeName': 'testing-name', 40 | 'themeDesc': 'mock theme decription', 41 | 'drupalVersion': 'd7', 42 | 'themeStyles': 'n', 43 | 'features': [] 44 | }); 45 | this.app.options['skip-install'] = true; 46 | this.app.run({}, function () { 47 | helpers.assertFiles(expected); 48 | done(); 49 | }); 50 | }); 51 | 52 | it('creates expected files for SASS support', function (done) { 53 | var expected = [ 54 | // add files you expect to exist here. 55 | 'sass/_config.scss', 56 | 'sass/editor.scss', 57 | 'sass/style.scss' 58 | ]; 59 | 60 | helpers.mockPrompt(this.app, { 61 | 'themeName': 'testing-name', 62 | 'themeDesc': 'mock theme decription', 63 | 'drupalVersion': 'd7', 64 | 'themeStyles': 's', 65 | 'features': [] 66 | }); 67 | this.app.options['skip-install'] = true; 68 | this.app.run({}, function () { 69 | helpers.assertFiles(expected); 70 | done(); 71 | }); 72 | }); 73 | 74 | it('creates expected files for COMPASS support', function (done) { 75 | var expected = [ 76 | // add files you expect to exist here. 77 | 'config.rb' 78 | ]; 79 | 80 | helpers.mockPrompt(this.app, { 81 | 'themeName': 'testing-name', 82 | 'themeDesc': 'mock theme decription', 83 | 'drupalVersion': 'd7', 84 | 'themeStyles': 'c', 85 | 'features': [] 86 | }); 87 | this.app.options['skip-install'] = true; 88 | this.app.run({}, function () { 89 | helpers.assertFiles(expected); 90 | done(); 91 | }); 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var path = require('path'); 4 | var yeoman = require('yeoman-generator'); 5 | var _ = require('lodash'); 6 | _.str = require('underscore.string'); 7 | var drupalLogo = require('../common/drupal-logo'); 8 | 9 | _.mixin(_.str.exports()); 10 | 11 | 12 | var Generator = module.exports = function Generator(args, options, config) { 13 | yeoman.generators.Base.apply(this, arguments); 14 | 15 | // determine theme name from cwd and form a theme name according to Drupal standards 16 | this.dirName = path.basename(process.cwd()); 17 | this.themeName = _(_.slugify(this.dirName)).underscored(); 18 | 19 | // argument definition for drush and fallback use 20 | this.argument('sourcepath', { 21 | desc: 'starterkit path', 22 | required: false, 23 | optional: true, 24 | type: String, 25 | defaults: 'default' 26 | }); 27 | 28 | this.argument('destpath', { 29 | desc: 'destination path', 30 | required: false, 31 | optional: true, 32 | type: String, 33 | defaults: this.dirName 34 | }); 35 | 36 | 37 | this.starterkitConfig = (this.sourcepath != 'default') ? JSON.parse(this.readFileAsString(path.join(this.sourcepath, 'package.json'))) : null; 38 | 39 | this.on('end', function () { 40 | this.installDependencies({ skipInstall: options['skip-install'] }); 41 | }); 42 | 43 | this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json'))); 44 | 45 | console.log(drupalLogo.logo); 46 | 47 | this.hookFor('drupaltheme:common', { 48 | args: args 49 | }); 50 | 51 | // set sourceRoot for starterkit templates 52 | if (this.sourcepath == 'default') { 53 | this.sourceRoot(path.join(__dirname, '../default/templates/')); 54 | this.env.register(path.join(__dirname, '../default/index.js'), 'drupaltheme:starterkit'); 55 | } 56 | else { 57 | this.sourceRoot(this.sourcepath); 58 | this.env.register(path.join(this.sourcepath, 'index.js'), 'drupaltheme:starterkit'); 59 | } 60 | this.hookFor('drupaltheme:starterkit', { 61 | args: args 62 | }); 63 | 64 | 65 | 66 | }; 67 | 68 | util.inherits(Generator, yeoman.generators.Base); 69 | 70 | Generator.prototype.askFor = function askFor() { 71 | var cb = this.async(); 72 | 73 | var prompts = [ 74 | { 75 | name: 'themeName', 76 | message: 'Name your theme:', 77 | default: this.themeName 78 | 79 | }, 80 | { 81 | name: 'themeDesc', 82 | message: 'Describe your theme:' 83 | } 84 | ]; 85 | 86 | this.prompt(prompts, function (props) { 87 | this.themeName = this.env.themeName = props.themeName; 88 | this.themeMachineName = this.env.themeMachineName = _.underscored((_.slugify(this.themeName))); 89 | this.themeDesc = this.env.themeDesc = props.themeDesc; 90 | // set destination path according to destination path + theme name 91 | if (this.destpath != this.dirName) { 92 | this.dirName = path.join(this.destpath, this.themeMachineName); 93 | this.destinationRoot(this.dirName); 94 | } 95 | cb(); 96 | }.bind(this)); 97 | }; 98 | -------------------------------------------------------------------------------- /common/drupal-logo.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk'); 2 | 3 | module.exports.logo = 4 | chalk.blue('\n O ') + 5 | chalk.blue('\n 8=$ ') + 6 | chalk.blue('\n D.~$$8 ') + 7 | chalk.blue('\n ,') + chalk.white('..') + chalk.blue('=$$$$$O ') + 8 | chalk.blue('\n O') + chalk.white('...') + chalk.blue('~~$$$$$$$$$O ') + 9 | chalk.blue('\n O') + chalk.white('.....') + chalk.blue('=~$$$$$$$$$$$$$ ') + 10 | chalk.blue('\n 8') + chalk.white('......') + chalk.blue('==$$$$$$$$$$$$$$$$ ') + 11 | chalk.blue('\n O') + chalk.white('......') + chalk.blue('=~$$$$$$$$$$$$$$$$$$$O ') + 12 | chalk.blue('\n ,') + chalk.white('....') + chalk.blue('===$$$$$$$$$$$$$$$$$$$$$$Z ') + 13 | chalk.blue('\n =') + chalk.white('..') + chalk.blue('~==$$$$$$$$$$$$$$$$$$$$$$$$$$O ') + 14 | chalk.blue('\n $~~=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$OO ') + 15 | chalk.blue('\n O$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$OOO8 ') + 16 | chalk.blue('\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ZOOOOOOOO ') + 17 | chalk.blue('\n $$$$$$$$$$$$$') + chalk.white('......') + chalk.blue('$$$$$$$$$$OOOOOOOOOO ') + 18 | chalk.blue('\n $$$$$$$$$$$') + chalk.white('..........') + chalk.blue(':$$$$$OOOOO') + chalk.white('.....') + chalk.blue('OO ') + 19 | chalk.blue('\n 8$$$$$$$$') + chalk.white('...............') + chalk.blue('$OOOO') + chalk.white('.........') + chalk.blue('O ') + 20 | chalk.blue('\n $$$$$$$$') + chalk.white('............................') + chalk.blue('. ') + 21 | chalk.blue('\n O$$$$$$Z') + chalk.white('................') + chalk.blue('ZOZ') + chalk.white('.........') + chalk.blue('Z ') + 22 | chalk.blue('\n $$$$$$$') + chalk.white('.............') + chalk.blue('$OOOOOOZ') + chalk.white('......') + chalk.blue('. ') + 23 | chalk.blue('\n O$$$$$Z') + chalk.white('.........') + chalk.blue('OOOO') + chalk.white('.....') + chalk.blue('OOO') + chalk.white('... ') + chalk.blue('. ') + 24 | chalk.blue('\n OOOOOOOOZZZOOOOOOO.OOOOO.OOOOZ$ ') + 25 | chalk.blue('\n OOOOOOOOOOOOOOOOOOOOOOOOOOO$O ') + 26 | chalk.blue('\n OOOOOOOOOO') + chalk.white('..') + chalk.blue('OOOOOOOOZ') + chalk.white('..') + chalk.blue('ZZ ') + 27 | chalk.blue('\n 8OOOOOOOOO') + chalk.white('........') + chalk.blue('O$O ') + 28 | chalk.blue('\n OOOOOOOOOOOZOD ') + 29 | chalk.blue('\n ^^ ') + 30 | chalk.blue('\n ___ ___ _ _ ___ _ _ _____ _ _ ___ __ __ ___ ') + 31 | chalk.blue('\n | \\| _ \\ | | | _ \\/_\\ | | |_ _| || | __| \\/ | __|') + 32 | chalk.blue('\n | |) | / |_| | _/ _ \\| |__ | | | __ | _|| |\\/| | _| ') + 33 | chalk.blue('\n |___/|_|_\\\\___/|_|/_/ \\_\\____| |_| |_||_|___|_| |_|___|') + 34 | '\n' + 35 | '\n'; 36 | -------------------------------------------------------------------------------- /default/templates/d7/templates/page.tpl.php: -------------------------------------------------------------------------------- 1 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 33 | 34 | 35 | 36 |
37 | 38 |
39 | 40 | 41 |
42 | 43 | 44 | 47 | 48 | 49 | 50 | 55 |
56 | 57 |
58 | 59 | 60 |
61 | 62 | 63 |
64 | 65 |
66 | 67 | 68 |
69 | 70 |
71 | 72 | 73 |

74 | 75 | 76 | 77 | 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 |
90 | 91 | 92 | 95 | 96 | 97 | 98 | 101 | 102 | 103 |
104 | 105 | 106 |
107 | 108 |
109 | 110 | 111 |
112 | -------------------------------------------------------------------------------- /default/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var path = require('path'); 4 | var yeoman = require('yeoman-generator'); 5 | var _ = require('lodash'); 6 | _.str = require('underscore.string'); 7 | 8 | // Mix in non-conflicting functions to Underscore namespace and 9 | // Generators. 10 | // 11 | // Examples 12 | // 13 | // this._.humanize('stuff-dash') 14 | // this._.classify('hello-model'); 15 | // 16 | _.mixin(_.str.exports()); 17 | 18 | var DrupalthemeGenerator = module.exports = function DrupalthemeGenerator(args, options, config) { 19 | yeoman.generators.Base.apply(this, arguments); 20 | 21 | this.themeName = this.env.themeName || 'nameless'; 22 | this.themeDesc = this.env.themeDesc || 'nameless theme description'; 23 | this.themeMachineName = this.env.themeMachineName || 'nameless'; 24 | 25 | this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json'))); 26 | }; 27 | 28 | util.inherits(DrupalthemeGenerator, yeoman.generators.Base); 29 | 30 | DrupalthemeGenerator.prototype.askFor = function askFor() { 31 | var cb = this.async(); 32 | 33 | 34 | var prompts = [ 35 | { 36 | name: 'drupalVersion', 37 | message: 'Which Drupal version?', 38 | type: 'list', 39 | choices: [ 40 | { 41 | name: 'Drupal 7', 42 | value: 'd7' 43 | }, 44 | { 45 | name: 'Drupal 8', 46 | value: 'd8' 47 | } 48 | ] 49 | }, 50 | { 51 | name: 'themeStyles', 52 | message: 'Add Sass, or Compass or NO css preprocessor support', 53 | type: 'list', 54 | choices: [{ 55 | name: 'SCSS', 56 | value: 's' 57 | }, { 58 | name: 'COMPASS', 59 | value: 'c' 60 | }, { 61 | name: 'NO (plain CSS)', 62 | value: 'n' 63 | }] 64 | }, 65 | { 66 | type: 'checkbox', 67 | name: 'features', 68 | message: 'What more would you like?', 69 | choices: [{ 70 | name: 'Bootstrap for Sass/Compass', 71 | value: 'compassBootstrap', 72 | checked: false 73 | }, { 74 | name: 'Frondly - the (Drupal-)friendly front-end framework', 75 | value: 'frondly', 76 | checked: false 77 | }] 78 | } 79 | ]; 80 | 81 | this.prompt(prompts, function (props) { 82 | 83 | var features = props.features; 84 | this.styleSASS = (props.themeStyles === 's') ? true : false; 85 | this.styleCOMPASS = (props.themeStyles === 'c') ? true : false; 86 | this.drupalVersion = props.drupalVersion; 87 | this.compassBootstrap = features.indexOf('compassBootstrap') !== -1; 88 | this.frondly = features.indexOf('frondly') !== -1; 89 | 90 | cb(); 91 | }.bind(this)); 92 | }; 93 | 94 | DrupalthemeGenerator.prototype.app = function app() { 95 | this.mkdir('js'); 96 | this.mkdir('css'); 97 | this.mkdir('images'); 98 | if (this.styleSASS || this.styleCOMPASS || this.compassBootstrap || this.frondly) { 99 | this.mkdir('sass'); 100 | } 101 | }; 102 | 103 | DrupalthemeGenerator.prototype.themeStyles = function themeStyles() { 104 | this.template('_style.css', 'css/style.css'); 105 | this.template('_editor.css', 'css/editor.css'); 106 | if (this.styleCOMPASS || this.compassBootstrap || this.frondly) { 107 | this.template('_config.rb', 'config.rb'); 108 | } 109 | if (this.styleSASS || this.styleCOMPASS || this.compassBootstrap || this.frondly) { 110 | this.template('__config.scss', 'sass/_config.scss'); 111 | this.template('_editor.scss', 'sass/editor.scss'); 112 | this.template('_style.scss', 'sass/style.scss'); 113 | } 114 | }; 115 | 116 | DrupalthemeGenerator.prototype.themeScripts = function themeScripts() { 117 | var tn = this.themeMachineName; 118 | this.template('_javascript.js', 'js/' + tn + '.js'); 119 | }; 120 | 121 | DrupalthemeGenerator.prototype.themeInfo = function themeInfo() { 122 | var tn = this.themeMachineName; 123 | // Drupal 7 124 | if (this.drupalVersion === 'd7') { 125 | this.template('d7/_theme.info', tn + '.info'); 126 | } 127 | // Drupal 8 128 | if (this.drupalVersion === 'd8') { 129 | this.template('d8/_theme.info.yml', tn + '.info.yml'); 130 | } 131 | }; 132 | 133 | DrupalthemeGenerator.prototype.themeTemplates = function themeTemplates() { 134 | var tn = this.themeMachineName; 135 | // Drupal 7 136 | if (this.drupalVersion === 'd7') { 137 | this.template('d7/_template.php', 'template.php'); 138 | this.directory('d7/templates', 'templates'); 139 | } 140 | // Drupal 8 141 | if (this.drupalVersion === 'd8') { 142 | this.template('d8/_theme.theme', tn + '.theme'); 143 | } 144 | }; 145 | 146 | DrupalthemeGenerator.prototype.themeImages = function themeImages() { 147 | this.copy('_screenshot.png', 'screenshot.png'); 148 | this.copy('_logo.png', 'logo.png'); 149 | }; 150 | 151 | DrupalthemeGenerator.prototype.bowerFiles = function bowerFiles() { 152 | this.template('_bower.json', 'bower.json'); 153 | this.copy('bowerrc', '.bowerrc'); 154 | }; 155 | 156 | DrupalthemeGenerator.prototype.packageFiles = function packageFiles() { 157 | this.packageInfo = { 158 | "name": this.themeMachineName, 159 | "version": "0.0.0" 160 | }; 161 | this.template('_package.json', 'package.json'); 162 | }; 163 | -------------------------------------------------------------------------------- /default/templates/d7/_template.php: -------------------------------------------------------------------------------- 1 | _preprocess_maintenance_page() calls 11 | * this function to have consistent variables. 12 | */ 13 | function <%= themeMachineName %>_preprocess_html(&$variables, $hook) { 14 | // Add variables and paths needed for HTML5 and responsive support. 15 | $variables['base_path'] = base_path(); 16 | $variables['theme_path'] = drupal_get_path('theme', '<%= themeMachineName %>'); 17 | 18 | $variables['add_responsive_meta'] = TRUE; 19 | 20 | // Attributes for html element. 21 | $variables['html_attributes_array'] = array( 22 | 'lang' => $variables['language']->language, 23 | 'dir' => $variables['language']->dir, 24 | 'class' => array('no-js'), 25 | ); 26 | } 27 | 28 | /** 29 | * Override or insert variables into the html templates. 30 | * 31 | * @param $variables 32 | * An array of variables to pass to the theme template. 33 | * @param $hook 34 | * The name of the template being rendered ("html" in this case.) 35 | */ 36 | function <%= themeMachineName %>_process_html(&$variables, $hook) { 37 | // Flatten out html_attributes. 38 | $variables['html_attributes'] = drupal_attributes($variables['html_attributes_array']); 39 | } 40 | 41 | /** 42 | * Override or insert variables into the page template. 43 | * 44 | * @param $variables 45 | * An array of variables to pass to the theme template. 46 | * @param $hook 47 | * The name of the template being rendered ("page" in this case.) 48 | */ 49 | function <%= themeMachineName %>_preprocess_page(&$variables, $hook) { 50 | // add a variable for debugging, 51 | // like showing all region containers even if they have no content 52 | $variables['debug'] = FALSE; 53 | 54 | // remove default message from main content if there is no content created yet. 55 | unset($variables['page']['content']['system_main']['default_message']); 56 | } 57 | 58 | /** 59 | * Override or insert variables into the page template. 60 | * 61 | * @param $variables 62 | * An array of variables to pass to the theme template. 63 | */ 64 | function <%= themeMachineName %>_process_page(&$variables) { 65 | 66 | // Since the title and the shortcut link are both block level elements, 67 | // positioning them next to each other is much simpler with a wrapper div. 68 | if (!empty($variables['title_suffix']['add_or_remove_shortcut']) && $variables['title']) { 69 | // Add a wrapper div using the title_prefix and title_suffix render elements. 70 | $variables['title_prefix']['shortcut_wrapper'] = array( 71 | '#markup' => '
', 72 | '#weight' => 100, 73 | ); 74 | $variables['title_suffix']['shortcut_wrapper'] = array( 75 | '#markup' => '
', 76 | '#weight' => -99, 77 | ); 78 | // Make sure the shortcut link is the first item in title_suffix. 79 | $variables['title_suffix']['add_or_remove_shortcut']['#weight'] = -100; 80 | } 81 | } 82 | 83 | /** 84 | * Override or insert variables into the node templates. 85 | * 86 | * @param $variables 87 | * An array of variables to pass to the theme template. 88 | * @param $hook 89 | * The name of the template being rendered ("node" in this case.) 90 | */ 91 | function <%= themeMachineName %>_preprocess_node(&$variables, $hook) { 92 | // Add a suggestion based on view_mode. 93 | $variables['theme_hook_suggestions'][] = 'node__' . $variables['view_mode']; 94 | $variables['theme_hook_suggestions'][] = 'node__' . $variables['type'] . '__' . $variables['view_mode']; 95 | 96 | // Add a class based on view_mode. 97 | $variables['classes_array'][] = 'node-' . drupal_html_class($variables['view_mode']); 98 | $variables['classes_array'][] = 'node-' . drupal_html_class($variables['type']) . '-' . drupal_html_class($variables['view_mode']); 99 | 100 | // Add $unpublished variable. 101 | $variables['unpublished'] = (!$variables['status']) ? TRUE : FALSE; 102 | 103 | // Add pubdate to submitted variable. 104 | $variables['pubdate'] = ''; 105 | if ($variables['display_submitted']) { 106 | $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['pubdate'])); 107 | } 108 | 109 | $variables['title_attributes_array']['class'][] = 'node-title'; 110 | } 111 | 112 | /** 113 | * Override or insert variables into the comment templates. 114 | * 115 | * @param $variables 116 | * An array of variables to pass to the theme template. 117 | * @param $hook 118 | * The name of the template being rendered ("comment" in this case.) 119 | */ 120 | function <%= themeMachineName %>_preprocess_comment(&$variables, $hook) { 121 | // If comment subjects are disabled, don't display them. 122 | if (variable_get('comment_subject_field_' . $variables['node']->type, 1) == 0) { 123 | $variables['title'] = ''; 124 | } 125 | 126 | // Add pubdate to submitted variable. 127 | $variables['pubdate'] = ''; 128 | $variables['submitted'] = t('!username commented on !datetime', array('!username' => $variables['author'], '!datetime' => $variables['pubdate'])); 129 | 130 | // Zebra striping. 131 | if ($variables['id'] == 1) { 132 | $variables['classes_array'][] = 'first'; 133 | } 134 | if ($variables['id'] == $variables['node']->comment_count) { 135 | $variables['classes_array'][] = 'last'; 136 | } 137 | $variables['classes_array'][] = $variables['zebra']; 138 | 139 | $variables['title_attributes_array']['class'][] = 'comment-title'; 140 | } 141 | 142 | /** 143 | * Override or insert variables into the taxonomy term templates. 144 | * 145 | * @param $variables 146 | * An array of variables to pass to the theme template. 147 | * @param $hook 148 | * The name of the template being rendered ("block" in this case.) 149 | */ 150 | function <%= themeMachineName %>_preprocess_taxonomy_term(&$variables) { 151 | // Add a suggestion based on view_mode. 152 | $variables['theme_hook_suggestions'][] = 'term__' . $variables['view_mode']; 153 | $variables['theme_hook_suggestions'][] = 'term__' . $variables['vocabulary_machine_name'] . '__' . $variables['view_mode']; 154 | 155 | // Add a class based on view_mode. 156 | $variables['classes_array'][] = 'term-' . drupal_html_class($variables['view_mode']); 157 | $variables['classes_array'][] = 'term-' . drupal_html_class($variables['vocabulary_machine_name']) . '-' . drupal_html_class($variables['view_mode']); 158 | 159 | $variables['title_attributes_array']['class'][] = 'term-title'; 160 | } 161 | 162 | /** 163 | * Override or insert variables into the block templates. 164 | * 165 | * @param $variables 166 | * An array of variables to pass to the theme template. 167 | * @param $hook 168 | * The name of the template being rendered ("block" in this case.) 169 | */ 170 | function <%= themeMachineName %>_preprocess_block(&$variables, $hook) { 171 | 172 | $variables['classes_array'][] = $variables['block_zebra']; 173 | 174 | $variables['title_attributes_array']['class'][] = 'block-title'; 175 | 176 | // Add Aria Roles via attributes. 177 | // Suggest a navigation block template if appropriate. 178 | switch ($variables['block']->module) { 179 | case 'admin': 180 | switch ($variables['block']->delta) { 181 | case 'menu': 182 | // Suggest a navigation block template and set role 183 | $variables['theme_hook_suggestions'][] = 'block__navigation'; 184 | $variables['attributes_array']['role'] = 'navigation'; 185 | break; 186 | } 187 | break; 188 | case 'system': 189 | switch ($variables['block']->delta) { 190 | case 'main': 191 | // Note: the "main" role goes in the page.tpl, not here. 192 | // Use a template with no wrapper for the page's main content. 193 | $variables['theme_hook_suggestions'][] = 'block__no_wrapper'; 194 | break; 195 | case 'help': 196 | case 'powered-by': 197 | $variables['attributes_array']['role'] = 'complementary'; 198 | break; 199 | default: 200 | // Any other "system" block is a menu block. 201 | $variables['theme_hook_suggestions'][] = 'block__navigation'; 202 | $variables['attributes_array']['role'] = 'navigation'; 203 | break; 204 | } 205 | break; 206 | case 'menu': 207 | // add a class indicating the menu name 208 | $variables['classes_array'][] = drupal_html_class($variables['block']->delta); 209 | case 'menu_block': 210 | case 'blog': 211 | case 'book': 212 | case 'comment': 213 | case 'forum': 214 | case 'shortcut': 215 | case 'statistics': 216 | $variables['theme_hook_suggestions'][] = 'block__navigation'; 217 | $variables['attributes_array']['role'] = 'navigation'; 218 | break; 219 | case 'search': 220 | $variables['attributes_array']['role'] = 'search'; 221 | break; 222 | case 'help': 223 | case 'aggregator': 224 | case 'locale': 225 | case 'poll': 226 | case 'profile': 227 | $variables['attributes_array']['role'] = 'complementary'; 228 | break; 229 | case 'node': 230 | switch ($variables['block']->delta) { 231 | case 'syndicate': 232 | $variables['attributes_array']['role'] = 'complementary'; 233 | break; 234 | case 'recent': 235 | $variables['theme_hook_suggestions'][] = 'block__navigation'; 236 | $variables['attributes_array']['role'] = 'navigation'; 237 | break; 238 | } 239 | break; 240 | case 'user': 241 | switch ($variables['block']->delta) { 242 | case 'login': 243 | $variables['attributes_array']['role'] = 'form'; 244 | break; 245 | case 'new': 246 | case 'online': 247 | $variables['attributes_array']['role'] = 'complementary'; 248 | break; 249 | } 250 | break; 251 | case 'views': 252 | // Add view css classes to block 253 | if (isset($variables['elements']['#views_contextual_links_info']['views_ui']['view']->display['default']->display_options['css_class'])) { 254 | $views_css_classes = explode(' ', $variables['elements']['#views_contextual_links_info']['views_ui']['view']->display['default']->display_options['css_class']); 255 | $variables['classes_array'] = array_merge($variables['classes_array'], $views_css_classes); 256 | } 257 | break; 258 | } 259 | // In some regions, visually hide the title of any block, but leave it accessible. 260 | $region = $variables['block']->region; 261 | if ($region == 'header' || 262 | $region == 'navigation' || 263 | $region == 'highlighted') { 264 | $variables['title_attributes_array']['class'][] = 'element-invisible'; 265 | } 266 | } 267 | 268 | /** 269 | * Override or insert variables into the block templates. 270 | * 271 | * @param $variables 272 | * An array of variables to pass to the theme template. 273 | * @param $hook 274 | * The name of the template being rendered ("block" in this case.) 275 | */ 276 | function <%= themeMachineName %>_process_block(&$variables, $hook) { 277 | // Drupal 7 should use a $title variable instead of $block->subject. 278 | $variables['title'] = $variables['block']->subject; 279 | } 280 | 281 | /** 282 | * Add some template suggestions 283 | * 284 | * @param $variables 285 | * An array of variables to pass to the theme template. 286 | */ 287 | function <%= themeMachineName %>_preprocess_panels_pane(&$variables) { 288 | $subtype = $variables['pane']->subtype; 289 | $layout = $variables['display']->layout; 290 | $variables['theme_hook_suggestions'][] = 'panels_pane__' . $layout; 291 | $variables['theme_hook_suggestions'][] = 'panels_pane__' . $subtype; 292 | $variables['theme_hook_suggestions'][] = 'panels_pane__' . $layout . '__' . $subtype; 293 | } 294 | 295 | /** 296 | * Implements hook_css_alter(). 297 | */ 298 | function <%= themeMachineName %>_css_alter(&$css) { 299 | 300 | // Remove Drupal default stylesheets 301 | $exclude = array( 302 | 'modules/system/system.base.css' => FALSE, 303 | 'modules/system/system.menus.css' => FALSE, 304 | 'modules/system/system.messages.css' => FALSE, 305 | 306 | 'modules/comment/comment.css' => FALSE, 307 | 308 | 'modules/node/node.css' => FALSE, 309 | 310 | // jQuery UI 311 | 'misc/ui/jquery.ui.core.css' => FALSE, 312 | 'misc/ui/jquery.ui.theme.css' => FALSE, 313 | 'misc/ui/jquery.ui.tabs.css' => FALSE, 314 | ); 315 | 316 | $css = array_diff_key($css, $exclude); 317 | 318 | // remove some contrib stylesheets 319 | $fuzzy_exclude = array('twocol.css', 'ds_2col_stacked.css', 'panels.css'); 320 | foreach ($css as $path => $meta) { 321 | foreach ($fuzzy_exclude as $css_file) { 322 | if (strpos($path, $css_file) !== FALSE) { 323 | unset($css[$path]); 324 | } 325 | } 326 | } 327 | } 328 | --------------------------------------------------------------------------------