├── .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 | >
18 |
19 |
20 |
21 | >
22 |
23 |
24 |
25 |
26 |
27 |
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 |
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 |
33 |
34 |
35 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/default/templates/d7/templates/comment.tpl.php:
--------------------------------------------------------------------------------
1 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | >
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
51 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Generator-drupaltheme
2 | [](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 |
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 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | instructions how to enable JavaScript in your web browser.');?>
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
95 |
96 |
97 |
98 |
101 |
102 |
103 |
104 |
105 |
106 |
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'] = '' . $variables['date'] . ' ';
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'] = '' . $variables['created'] . ' ';
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 |
--------------------------------------------------------------------------------