Yii 1.1: nsprite

A Yii based sprite generator extension
25 followers

The NSprite extension aims to help solve the problem of generating sprites for your application.

There are many great icon libraries that are ubiquitous on the web, - famfamfam - fugue Each of these have thousands of icons, a typical project uses a handfull of these.

This class allows you to dump the individual image files you want into a folder or set of folders. The class then generates the sprite from all the images in these folder(s) and publishes the sprite.png plus the generated sprite.css file into the assets folder.

Requirements

  • Tested with Yii 1.8. relies on the CAssetManager and the CFileHelper so it should work on Yii 1.0 and above.
  • GD php library
  • Tested on PHP 5.2 and 5.3, may also work on previous versions

Installation

  1. Download the sprite.zip package
  2. Extract it and place the sprite folder into your extensions folder
  3. The assets folder must be writable.
  4. Add the sprite component to you Yii app's confirguration

Usage

In you main config

'components'=>array(
    'sprite'=>array(
    'class'=>'ext.sprite.NSprite',
    // if you remove the imageFolderPsth setting it will use the icon folder within   
    // the sprite package (ext.sprite.icons)
    'imageFolderPath'=>array(
        Yii::getPathOfAlias('modules.project.images'),
        'path/to/another/folder'
    )
),

Then somewhere in your application you just have to register the css file.

Yii::app()->sprite->registerSpriteCss();

The css classes generated follow a convention. Each class will have a parent class (defaults to ".sprite", or ".icon") that set the background image to the generated sprite. Each icon/image in your set of image folders (set by "imageFolderPath") will have a class name equivalent to their relative file path within the imageFolderPath.

For example an image folder containing:

fam/add.png
myicons/groovy.png
fugue/pencil.png

Will generate the following css classes:

.sprite{background-image:url(sprite.png);}
.icon{display:inline;overflow:hidden;padding-left:18px;background-repeat:no-repeat;background-image:url(sprite.png);}
.fam-add{background-position:-16px 0px;width:6px;height:16px;}
.myicons-groovy{background-position:-16px -16px;width:16px;height:16px;}
.fugue-pencil{background-position:-16px -32px;width:16px;height:16px;}

And can be used like:

<div class="sprite fam-add"></div> <!-- use on block elements -->
<span class="icon fam-add"></span> <!-- use with 16px x 16px image inline -->

The .sprite class is the general purpose class that adds the sprite as a background image. Nothing more. The .icon class is a helper for sprite icons typically for famfamfam and fugue 16 x 16 pixel images for use with images 16px by 16px, the sprite generator does support all sizes of images but you may have to add css to suite your situation.

Obviously you can override the .sprite and .icon classes (and change their name) to provide the css trickery required for your application.

Resources

Change log

  • sprite.1.1
    • fixed bug on windows environment with the path generation resulting in an additional "-" appending all class names
    • removed .icon class being prepended to all image classes.

Total 10 comments

#17500 report it
le_top at 2014/06/23 05:59pm
Suggestion - transparent "CHtml::image" use

Hi May I suggest that the CHtml::image method would be overloaded in a class called 'YHtml' for instance.

When enabled, YHtml::image would not generate '' tags, but divs with backgrounds.

YHtml would then have an option to enable the use of sprites or not.

In a further step, sprite generation could gather image paths automatically, possibly create sprites with only the used images and store information about the used images to a file (when that is enabled).

It would make this extension more 'transparent' and easier to implement as we can continue to use something very similar to "CHtml::image".

#10793 report it
daxiang28 at 2012/11/24 12:29am
Modification to accept :hover state

I update line 194 to turn any file that ends with '_hover' or '-hover' into a :hover pseudo class with the following code:

$css .= '.'.preg_replace('/\-hover/i',':hover',$image['name']).'{';

Good stuff. Also, noticed a bunch of echo statements that I removed.

Steve

#9206 report it
pmaselkowski at 2012/07/28 08:56am
Diff for changes

Here is diff for my proposed changes:

app/protected/extensions/sprite/NSprite.php |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
 
diff --git a/app/protected/extensions/sprite/NSprite.php b/app/protected/extensions/sprite/NSprite.php
index d1a9b87..3920e1b 100644
--- a/app/protected/extensions/sprite/NSprite.php
+++ b/app/protected/extensions/sprite/NSprite.php
@@ -59,6 +59,8 @@ Class NSprite extends CApplicationComponent
     * @var type 
     */
    public $cssIconClass = 'icon';
+
+   public $cssIconPrefix = '';
 
    /**
     * array of image paths relative to the NSprite::$imageFolderPath to include in the sprite, without a preceeding slash
@@ -87,7 +89,7 @@ Class NSprite extends CApplicationComponent
     * @return string
     */
    public function getAssetFolder(){
-       return dirname(__FILE__).DIRECTORY_SEPARATOR.'assets';
+       return Yii::app()->getRuntimePath() . '/nsprite';
    }
 
    /**
@@ -110,7 +112,7 @@ Class NSprite extends CApplicationComponent
        // check if we need to generate the sprite
        // if the asset folder exists we will assume we do not 
        // want to regenerate the sprite
-       if(!file_exists($this->getPublishedAssetsPath().'/sprite.png')){
+       if(!file_exists($this->getAssetFolder()) || !file_exists($this->getPublishedAssetsPath().'/sprite.png')){
            $this->generate();
        }
        return Yii::app()->getAssetManager()->publish($this->getAssetFolder());
@@ -148,6 +150,10 @@ Class NSprite extends CApplicationComponent
        // publish the path
        if(empty($this->sprites))
            $this->findFiles();
+       if(!file_exists($this->getAssetFolder()))
+       {
+           mkdir($this->getAssetFolder());
+       }
        $this->_generateImageData();
        $this->_generateImage();
        $this->_generateCss();
@@ -192,7 +198,7 @@ Class NSprite extends CApplicationComponent
        foreach($this->_images as $image) 
        { 
            echo $image['name'];
-           $css .= '.'.$image['name'].'{';
+           $css .= '.'.$this->cssIconPrefix.$image['name'].'{';
            $css .= 'background-position:'.($image['width'] - $total['width']).'px '.($top - $total['height']).'px;'; 
            $css .= 'width:'.$image['width'].'px;';
            $css .= 'height:'.$image['height'].'px;';
#9203 report it
pmaselkowski at 2012/07/28 08:25am
Some of my thoughts

Very good extension, my few cents:

  • It echoes some data on first load, echo at lines 194, 224
  • I think icon class should have configurable prefix so i could get names like 'icon-*'
  • You could use runtime folder for assets ie Yii::getPathOfAlias('application.runtime.nsprite')
#5007 report it
nisteve at 2011/09/05 02:57pm
Epi - the folder path '' does not exist

Hi Epi, check your settings in your main config file. This error occurs when the imageFolderPath property is not set or not a correct directory.

#4820 report it
epi at 2011/08/19 05:56am
where to put Yii::app()->sprite->registerSpriteCss();

I don't know where to put Yii::app()->sprite->registerSpriteCss(); I tried at layout main, it didn't work.

The error shows : The folder path '' does not exist.

please help. thanks

#4644 report it
kangkang at 2011/07/28 09:23pm
CTRL+F is useful~

download link is on the right, just search "Downloads" :)

#4617 report it
yiqing95 at 2011/07/26 02:24pm
great extension ,

interesting extension! never thought we can generate css from a image folder ! maybe every thing be able to be generated :D, just imagine ! thanks for the gii , the ror ,take us the scaffold ! then we can daringly think what can be generate by program ! hehe

           cheers ! yiier
#4614 report it
nisteve at 2011/07/26 11:49am
Ok uploaded now

Hi Melicerte,

The class is uploaded now :-)

#4612 report it
Gregoire at 2011/07/26 10:01am
where is the class?

That extension looks interesting to me and I'm willing to test it. Nevertheless, there is nothing to download (yet?)

Leave a comment

Please to leave your comment.

Create extension