twolfson / gulp.spritesmith

Convert a set of images into a spritesheet and CSS variables via gulp
The Unlicense
1.08k stars 81 forks source link

Get source folder name within custom CSS template #113

Closed WhereJuly closed 7 years ago

WhereJuly commented 7 years ago

First thanks a lot for the great product!

Sorry to bother you but I looked into the documentation, tried some options, and I did not find how to get a reference to my source folder name from within the custom Mustache template.

The ultimate goal is to be able to insert the source folder name within the CSS class selector name generated by Spritesmith.

The background is that I generate multiple different pairs of folder.css + folder.png with Spritesmith. I do all the things with Gulp, like reading multiple nested source folders and make the desired output (as per below). The only thing I miss is getting the source folder name into my CSS something like .spriteprefix-folder-spritename {CSS rules}. I use cssOpts.cssSelector (see below) but I have no effect in my CSS output.

Currently I use this custom Musache template:

.sprite {
  background-image: url({{{spritesheet.image}}});
  display: block;
}

{{#sprites}}
.sprite-{{name}} {
  background-position: {{px.offset_x}} {{px.offset_y}};
  width: {{px.width}};
  height: {{px.height}};
}
{{/sprites}}

via this Gulp script:

gulp.task('make-sprites', function() {

    // Multiple folders solution taken from here
    // https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-task-steps-per-folder.md

    var sprite_path = {
        src: 'z_design/images/unprocessed/sprites/src/',
        dest: 'z_design/images/unprocessed/sprites/dest/'
    }

    var folders = getFolders(sprite_path.src);

    var tasks = folders.map(function(folder) {
        gutil.log('Making sprites from folder: ' + folder);
        makeSprites(folder);
    });

    function makeSprites(folder) {
        var spriteData = gulp.src(sprite_path.src + folder + '/**/*.*')
            .pipe(spritesmith({
                algorithm: 'left-right',
                imgName: 'sprites-' + folder + '.png',
                cssName: 'sprites-' + folder + '.css',
                cssTemplate: './spritesmith.tpl.mustache',
                cssOpts: {
                    cssSelector: function(sprite) {
                        return folder + '-' + sprite.name;
                    }
                }
            }))
            .on('error', function(err) {
                console.log(err)
            });
        return spriteData.pipe(gulp.dest(sprite_path.dest));
    }
});

function getFolders(dir) {
    return fs.readdirSync(dir)
        .filter(function(file) {
            return fs.statSync(path.join(dir, file)).isDirectory();
        });
}

And I get the following result (excerpt):

.sprite {
  background-image: url(sprites-general.png);
  background-image: url();
  display: block;
}

.sprite-logo-lwr {
  background-position: -95px 0px;
  width: 119px;
  height: 71px;
}
.sprite-main-menu-mark {
  background-position: 0px 0px;
  width: 95px;
  height: 30px;
}
.sprite-vignette-invert-big {
  background-position: -628px 0px;
  width: 210px;
  height: 229px;
}

What I want to get is:

twolfson commented 7 years ago

cssOpts.cssSelector is specific to the CSS template itself:

https://github.com/twolfson/spritesheet-templates/blob/10.2.1/lib/templates/css.template.js#L16-L18

Since you are using a custom template and not that template, the option won't be used.

For your scenario, we expose the cssOpts variables as options in templates:

https://github.com/twolfson/gulp.spritesmith/tree/6.3.0#templating

This means your template should work if we update it to:

gulpfile.js:

spritesmith({
    algorithm: 'left-right',
    imgName: 'sprites-' + folder + '.png',
    cssName: 'sprites-' + folder + '.css',
    cssTemplate: './spritesmith.tpl.mustache',
    cssOpts: {
        folder: folder
    }
})

Template:

.sprite-{{options.folder}} {
  background-image: url({{{spritesheet.image}}});
  display: block;
}

{{#sprites}}
.sprite-{{options.folder}}-{{name}} {
  background-position: {{px.offset_x}} {{px.offset_y}};
  width: {{px.width}};
  height: {{px.height}};
}
{{/sprites}}
WhereJuly commented 7 years ago

Great! Thank you for quick answer. I knew it should be somewhere there.

The functionality is wide and spread over the different docs so that it somehow difficult to figure out the how to's for the particluar use case (or is it just me such a inexperienced?). Did not you think of making a "Usage Receipes" lik e.g. Browsersync or Gulp itself do?

I at least see 4 ones:

  1. The above case with multiple folders
  2. The use case of external template which is the part of the 1.
  3. Make .jpg sprites.
  4. Make responsive sprites (good post was already among the earlier closed issues).

I would contribute with cases description and 'how-to'. You would establish a new receipes.MD section, edit my input & publish. What do you think?

twolfson commented 7 years ago

We're aware that the current documentation is daunting. We've considered building a website for better documentation linking but we haven't had the time to invest in that.

With respect to explicit examples, we do have an examples section:

https://github.com/twolfson/gulp.spritesmith/tree/6.3.0#examples

We try not to over-do examples though as it can be hard to separate signal from noise at that point. From our perspective, examples/features should be added if there are enough recurring requests. In the ones you listed:

WhereJuly commented 7 years ago

Understood. Thank you again.