Ability to have sass components have separate output css files - gruntjs

I have a Drupal sub-theme set up with the following structure:
├── scss
│   ├── _helpers.scss
│   ├── component
│   │   ├── _dashboard.scss
│   │   ├── _alert.scss
│   │   ├── _badge.scss
│   │   ├── _branding.scss
│   │   ├── _navbar.scss
│   │   └── _user-login-form.scss
│   ├── element
│   │   ├── _header.scss
│   │   └── _main.scss
│   ├── styles.scss
This is my GruntFile.js:
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
css: {
files: '**/*.scss',
tasks: ['sass']
},
scripts: {
files: ['js/src/*.js'],
tasks: ['jshint', 'concat', 'uglify'],
options: {
nospawn: true,
livereload: 45729
}
},
options: {
livereload: true,
},
},
sass: {
dist: {
files: {
'css/styles.css': 'scss/styles.scss'
}
}
},
jshint: {
myFiles: ['js/src/*.js']
},
concat: {
options: {
separator: ';',
},
dist: {
src: ['../../../libraries/popper.js/dist/umd/popper.js', '../../../libraries/bootstrap/dist/js/bootstrap.js', 'js/src/*.js'],
dest: 'js/scripts.js',
},
},
uglify: {
my_target: {
files: {
'js/scripts.min.js': ['js/scripts.js']
}
}
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['watch']);
};
When I make a change in a scss file they compile into styles.css. In addition to this I would also like to have the ability to compile a css for each component.
For example:
├── scss
│   ├── _helpers.scss
....
....
└── components
├── component1
│   ├── component1.css
│   └── component1.scss
└── component2
├── component2.css
└── component2.scss
This way if component2 is only used on 1 page, I will only add that to that 1 page.
How can I set this up in my GruntFile?

Albertski. If I understood correctly you want to generate separate css files with that same scss folder structure. From what I'm seeing, you only need to take the _ (underline) before the name of the file you want and an automatically generated .css file will be generated.
To use this file wherever you want it is how you include it in your pages, for example use the "html--front.tpl.php" and there call your .css or include via hook.

Related

Gatsby how to import svg as background in scss correctly?

I'm getting error message Can't resolve '../../images/hero.svg' while
I'm trying to import svg image from images folder
and set it in header.scss as a background image: background-image: url('../../images/hero.svg');
My gatsby structure:
├─ src
├── scss
│ ├── main.scss
│ ├── modules
│ └──── header.scss
└── images
└── hero.svg
gatsby-config.js:
module.exports = {
siteMetadata: {
title: 'Test',
description: 'test',
author: '#gatsbyjs'
},
plugins: [
'gatsby-plugin-react-helmet',
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: `${__dirname}/src/images`
}
},
'gatsby-transformer-sharp',
'gatsby-plugin-sharp',
{
resolve: 'gatsby-plugin-manifest',
options: {
name: 'Test',
short_name: 'test',
start_url: '/',
background_color: '#663399',
theme_color: '#663399',
display: 'minimal-ui',
icon: 'src/images/android-chrome-192x192.png'
}
},
'gatsby-plugin-sass',
{
resolve: 'gatsby-plugin-react-svg',
options: {
rule: {
include: /\.inline\.svg$/
}
}
}
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
]
}
Thanks.
Problem solved by creating static folder and placing svg file inside of it. Needed to also update path in scss file to '/hero.svg'
import heroSvg from '/hero.svg';
In the css, scss or css in js etc
background-image: url(${heroSvg});
background-repeat: no-repeat;

Grunt - Output file in same folder

I have the following gruntfile.js:
module.exports = function(grunt) {
require('jit-grunt')(grunt);
grunt.initConfig({
uglify: {
options: {
manage: false
},
my_target: {
files: [{
expand: true,
cwd: 'assets/js',
src: '*.js',
dest: 'assets/js/min'
}]
},
},
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: [
{
expand: true, // Recursive
cwd: "assets", // The startup directory
src: ["**/*.less"], // Source files
dest: "assets/", // Destination
ext: ".css" // File extension
}
]
}
},
watch: {
styles: {
files: ['assets/**/*.less', 'assets/js/*.js'], // which files to watch
tasks: ['less', 'newer:uglify'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-newer');
grunt.registerTask('default', ['less', 'watch', 'newer:uglify']);
};
And the following path distribution:
| assets
|-- folder-1
|-- less
|-- folder-2
|-- less
With the current gruntfile.js, my output is a sub-level of the less folder:
| assets
|-- folder-1
|-- less
|-- css
|-- folder-2
|-- less
|-- css
But it should be on the same level of the LESS file. For example:
| assets
|-- folder-1
|-- less
|-- css
|-- folder-2
|-- less
|-- css
Any idea on how to modify my gruntfile.js? Is that possible?
If I understand your correctly, you want a css/ folder as a sibling of a less/ folder in each of your folder-{x}/ folders.
This can be done by adding the rename property to your less task config:
files: [
{
expand: true, // Recursive
cwd: "assets", // The startup directory
src: ["**/*.less"], // Source files
dest: "assets/", // Destination
ext: ".css", // File extension
rename: function (dest, src) {
return (dest + src.replace('less/', 'css/'));
}
}
]

Problems with grunt-sass-globbing plug-in structure

I'm attempting to use Dennis Becker's grunt-sass-globbing plug-in with libsass since libsass doesn't support sass-globbing. https://github.com/DennisBecker/grunt-sass-globbing
I've tried setting up a libsass project using the documentation that the developer has provided.
I'm having trouble figuring out exactly where files need to be placed and how imports should be called.
The below setup throws this error:
Running "sass_globbing:files" (sass_globbing) task
Running "sass:app" (sass) task
>> file to import not found or unreadable: layout/**/*
>> Current dir: /Users/dlahay/Documents/Workspaces/SusyLibsass/css/sass/
>> Line 3 Column 9 css/sass/main.scss
File structure:
css
|_ main.css
|_ sass
|_ layout
|_ _base.scss
|_ typography
|_ _base.scss
|_ _layoutMap.scss
|_ _typographyMap.scss
|_ main.scss
Gruntfile.js
grunt.initConfig({
sass_globbing: {
files: {
'css/sass/_layoutMap.scss': 'css/sass/layout/**/*.scss',
'css/sass/_typographyMap.scss': 'css/sass/typography/**/*.scss',
},
options: {
useSingleQuotes: false
}
},
// Grunt-sass
sass: {
app: {
files: [{
expand: true,
cwd: 'css/sass',
src: ['*.scss'],
dest: 'css',
ext: '.css'
}]
},
options: {
sourceMap: false,
outputStyle: 'nested',
imagePath: "../",
}
},
// Grunt-contrib-watch
watch: {
sass: {
files: ['css/sass/**/*'],
tasks: ['sass']
},
options: {
livereload: true,
spawn: false
}
},
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass-globbing');
grunt.registerTask('default', ['sass_globbing', 'sass', 'watch']);
main.scss:
#import "../../bower_components/susy/sass/susy";
#import "layout/**/*";
#import "typography/**/*";
I've also posted this question/issue on the grunt-sass-globbing repo.
Dennis Becker, the developer of grunt-sass-globbing helped me identify the two issues with my setup:
I didn't identify a target in the sass_globbing task in the Gruntfile:
sass_globbing: {
my_target: {
files: {
'css/sass/_layoutMap.scss': 'css/sass/layout/**/*.scss',
'css/sass/_typographyMap.scss': 'css/sass/typography/**/*.scss',
},
},
options: {
useSingleQuotes: false
}
},
My main.scss should have had the name of the map file in the #import:
#import "../../bower_components/susy/sass/susy";
#import "layoutMap";
#import "typographyMap";
Things are now working smoothly. Thanks, Dennis.
I have answered this on the GitHub repository website. It was just an issue with the Gruntfile.js configuration - thee was no target defined on the sass_globbing task.

HTML5 UP not working correctly in Django/Mezzanine project

I am trying to use HTML5 UP! with a Django/Mezzanine project and I am having problems getting skeljs to correctly load the style css files.
This is how I am loading files in my base.html file:
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "js/skel.min.js" %}"></script>
<script src="{% static "js/init.js" %}"></script>
<noscript>
<link rel="stylesheet" href="{% static "css/skel-noscript.css" %}" />
<link rel="stylesheet" href="{% static "css/style.css" %}" />
<link rel="stylesheet" href="{% static "css/style-wide.css" %}" />
</noscript>
this are my skeljs settings:
var _settings = {
skelJS: {
prefix: 'style',
resetCSS: true,
boxModel: 'border',
containers: 1200,
useOrientation: true,
breakpoints: {
'widest': { range: '*', containers: 1360, grid: { gutters: 50 }, hasStyleSheet: false },
'wide': { range: '-1680', containers: 1200, grid: { gutters: 40 } },
'normal': { range: '-1280', containers: 960, grid: { gutters: 30 }, lockViewport: true },
'narrow': { range: '-1000', containers: '100%', grid: { gutters: 25, collapse: true }, lockViewport: true },
'mobile': { range: '-640', containers: '100%', grid: { gutters: 10, collapse: true }, lockViewport: true }
}
}
};
This is the output that I get from the server:
[24/Apr/2014 17:08:46] "GET / HTTP/1.1" 200 23532
[24/Apr/2014 17:08:46] "GET /static/js/skel.min.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/js/jquery.min.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/js/init.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/css/mezzanine.css HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/css/bootstrap-theme.css HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/js/bootstrap-extras.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/css/bootstrap.css HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/grappelli/tinymce/jscripts/tiny_mce/tiny_mce.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/js/bootstrap.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/mezzanine/js/tinymce_setup.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/mezzanine/js/jquery.tools.overlay.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/mezzanine/js/jquery.form.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:46] "GET /static/mezzanine/js/editable.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:47] "GET /static/mezzanine/css/editable.css HTTP/1.1" 304 0
[24/Apr/2014 17:08:47] "GET /static/mezzanine/js/jquery.tools.toolbox.expose.js HTTP/1.1" 304 0
[24/Apr/2014 17:08:47] "GET /theme/static/css/style.css HTTP/1.1" 301 0
[24/Apr/2014 17:08:47] "GET /theme/static/css/style-wide.css HTTP/1.1" 301 0
[24/Apr/2014 17:08:47] "GET /theme/static/css/style-wide.css/ HTTP/1.1" 404 1629
[24/Apr/2014 17:08:47] "GET /theme/static/css/style.css/ HTTP/1.1" 404 1619
This is the folder structure for the relevant files.
├── manage.py
├── requirements.txt
├── settings.py
├── settings.pyc
├── static
│   └── media
├── theme
│   ├── admin.py
│   ├── admin.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── static
│   │   ├── css
│   │   │   ├── skel-noscript.css
│   │   │   ├── style.css
│   │   │   ├── style-mobile.css
│   │   │   ├── style-narrow.css
│   │   │   ├── style-normal.css
│   │   │   └── style-wide.css
Maybe you should config your static folder in setting.py like this:
STATICFILES_DIRS = (
"C:/myfile/project/python/mocs/static",
)
and config your static url like this:
STATIC_URL = '/static/'
and then you can put the static files into your codes,
make sure the url on pages should be a correct relative path from your static folder
Find the solution! The prefix was not set correctly.
var _settings = {
skelJS: {
prefix: 'static/css/style',
resetCSS: true,
boxModel: 'border',
containers: 1200,
useOrientation: true,
breakpoints: {
'widest': { range: '*', containers: 1360, grid: { gutters: 50 }, hasStyleSheet: false },
'wide': { range: '-1680', containers: 1200, grid: { gutters: 40 } },
'normal': { range: '-1280', containers: 960, grid: { gutters: 30 }, lockViewport: true },
'narrow': { range: '-1000', containers: '100%', grid: { gutters: 25, collapse: true }, lockViewport: true },
'mobile': { range: '-640', containers: '100%', grid: { gutters: 10, collapse: true }, lockViewport: true }
}
}
};

Grunt: including a generated file in usemin

This is the relevant part in my index.html:
<!-- build:js scripts/scripts.js -->
<script src="scripts/vendor/jquery.js"></script>
<script src="scripts/vendor/bootstrap.min.js"></script>
<script src="scripts/vendor/handlebars.runtime.js"></script>
<script src="scripts/vendor/ember.js"></script>
<script src="scripts/vendor/ember-data.js"></script>
<script src="scripts/templates.js"></script>
<script src="scripts/neuterapp.js"></script>
<!-- endbuild -->
(but the last two entrires are wrong, that is actually my problem)
This is the relevant part of the Gruntfile.js:
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>'
}
},
usemin: {
html: ['<%= yeoman.dist %>/*.html'],
css: ['<%= yeoman.dist %>/styles/*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
},
The problem that I have is that both templates.js and neuterapp.js are generated files, so they are not in <%= yeoman.app %>/scripts, but in <%= yeoman.dist %>/scripts.
This is my (simplified) directory structure:
webapp/
├── app
│   ├── app.js <--- for neuter
│   ├── controllers
│   ├── index.html
│   ├── models
│   ├── routes
│   ├── scripts
│   │   └── vendor <--- for usemin
│   ├── templates <--- for ember_templates
│   │   ├── template1.hbs
│   │   └── template2.hbs
│   └── views
├── dist
│   ├── index.html
│   └── scripts
│   ├── neuterapp.js <--- this must also be used for usemin!!!
│   └── templates.js <--- this must also be used for usemin!!!
└── Gruntfile.js
How can I tell usemin to include some generated files?
And in case this is needed, these are the configurations of neuter and ember_templates:
neuter: {
options: {
includeSourceURL: true
},
'<%= yeoman.dist %>/scripts/neuterapp.js': '<%= yeoman.app %>/app.js'
},
ember_templates: {
compile: {
options: {
templateName: function (sourceFile) {
return sourceFile.replace(/app\/templates\//, ''); // <%= yeoman.dist %>/scripts/
}
},
files: {
'<%= yeoman.dist %>/scripts/templates.js': [
'<%= yeoman.app %>/templates/**/*.hbs'
]
}
}
},
You might use the copy task to prepare what usemin needs in a temporary location.
What I suggest you do:
copy your needed app files from app to temp
Let your tasks which generate files output to temp
let your usemin & useminPrepare task run on temp and output to dist.

Resources