diff --git a/pla/cs/grunt-a-usemin.texy b/pla/cs/grunt-a-usemin.texy new file mode 100644 index 0000000000..654400dfbd --- /dev/null +++ b/pla/cs/grunt-a-usemin.texy @@ -0,0 +1,274 @@ +Nette a Grunt +=============== + +Jak snadno minifikovat js a css soubory pomoci Gruntu v Nette projektu + + +Proc toto spojeni? +-------------------- + +Protoze kazdy chce mit jen jeden javascript soubor a jeden css soubor. V dobe mobilniho internetu kde se kazdy request pocita nechceme hlavicky nasich stranek co vypadaji nejak takhle (v lepsim pripade) + +[* grunt-drupal.png *] + +Chceme jen jeden minifikovany soubor pro javascript a jeden minifikovany soubor pro css. A jelikoz na tyto ukoly se mi velmi dobre osvedcil Grunt a jeho kanonada pluginu, predstavim vam jednoduche reseni jak si tento proces automatizovat. + + +Co budem potrebovat. +------------- + +Cistou “instalaci” Nette sandboxu http://github.com/nette/sandbox a fungujici Grunt http://gruntjs.com. + +.[tip] +Grunt je JavaScript task runner, defakto neco jako Make ci Ant ale napsane v JavaScriptu. Existuje pro nej spousta zajimavych pluginu/tasku ktere jsou uzitecne ve frontendovem vyvoji (ale nejen i v nem) viz gruntjs.com/plugins. + +Jak zprovoznit grunt-cli: + +Grunt pohani node.js tudiz je treba mit nainstalovan node.js s package managerem npm (nodejs.org) + +nasledne do globalniho prostoru nainstalujeme grunt-cli +`npm install -g grunt-cli` + +pokud vse dobre dopadlo melo by se po zadani grunt --version objevit neco podobneho + + +[* grunt-version.png *] + + +V adresari ProjectGrunt si zprovoznime fungujici Nette Sandbox. Idealne pomoci composer prikazu + +`composer create-project nette/sandbox ProjectGrunt` + +[* grunt-nette-sandbox-composer.png *] + + +nasledne si zkontrolujeme obsah slozky + + +[* grunt-folder.png *] + +a po nastaveni webserveru a nastaveni log a temp (`chmod -R a+rw temp log`) bychom meli videt funguji stranku. ( nefunguje? Postupujte podle [Quick startu | http://doc.nette.org/en/2.1/quickstart/getting-started]) + + + +Jdeme na to +------------- + +do hlavniho adresare pridame soubor *package.json* ve kterem specifikujeme npm zavislosti pro nas grunt skript + +/-- +{ + "name": "ProjectGrunt", + "version": "1.0.0", + "devDependencies": { + "grunt": "~0.4.4", + "grunt-usemin": "~2.1.0", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-uglify": "~0.4.0", + "grunt-contrib-cssmin": "~0.9.0", + "grunt-nette-basepath": "~0.2.0" + } +} +\-- + +**grunt** - rikame ze chceme pouzivat Grunt ve verzi 0.4.4 + + +**grunt-usemin** - plugin pro prochazeni html souboru a dohledavani js a css souboru k dalsimu zpracovani + +**grunt-contrib-concat** - plugin pro spojovani vice souboru do jednoho + +**grunt-contrib-uglify** - plugin pro minifikaci javascript souboru + +**grunt-contrib-cssmin** - plugin pro minifikaci css souboru + +**grunt-nette-basepath** - plugin pro odstraneni latte promene {$basePath} + + +Instalaci provedeme prikazem `npm install` + +[* grunt-npm-install.png *] + +A nasledne do hlavniho adresare pridame jeste *Gruntfile.coffee* (muzete pouzit i Gruntfile.js ale z vlastni zkusenosti doporucuji Coffee, prece jen je tam o poznani mene zavorek, stredniku a vseho mozneho :-) ) + +/-- +module.exports = (grunt) -> + grunt.initConfig + useminPrepare: + html: ['app/templates/@layout.latte'] + options: + dest: '.' + + netteBasePath: + basePath: 'www' + options: + removeFromPath: ['app/templates/'] + + # These plugins provide necessary tasks. + grunt.loadNpmTasks 'grunt-contrib-concat' + grunt.loadNpmTasks 'grunt-contrib-uglify' + grunt.loadNpmTasks 'grunt-contrib-cssmin' + grunt.loadNpmTasks 'grunt-usemin' + grunt.loadNpmTasks 'grunt-nette-basepath' + + # Default task. + grunt.registerTask 'default', [ + 'useminPrepare' + 'netteBasePath' + 'concat' + 'uglify' + 'cssmin' + ] +\-- + +Zde je definicie jake tasky se maji nacist. Jak se chova hlavni task (to je ten co se spusti prikazem grunt) a konfigurace pro task useminPrepare a netteBasePath. Vice informaci jak funguje usemin plugin najdete na https://github.com/yeoman/grunt-usemin + +V nasem pripade si jeste overime konfiguraci pro netteBasePath kde rikame ze basePath se nachazi v adresari www a z duvodu jak funguje useminPrepare potrebujeme odsranit jeste zanoreni *app/templates* ktere k souborum plugin pridava. + +.[error] +pro platformu windows je mozne ze bude nutna drobna uprava konfigurace na +/-- +removeFromPath: ['app\\templates\\'] +\-- +(o problemu vim a casem ho snad vyresim) + + +Spustime minifikaci +----------------- + +Ted kdyz mame vse tak uz by nam melo jit spustit `grunt` , ale v tuto chvili skoncime s chybou jelikoz usemin plugin nenasel zadne bloky k minifikaci. + +[* grunt-usemin-error.png *] + +Tak si tam ty bloky pridame :) V souboru *@layout.latte* najdeme a obalime klasicke nacitani css a js + + +/--html + + + + + + +\-- + +a + +/--html + + + + + +\-- + +a ted by spustenim `grunt` mel najit nase definovane soubory v blocich a postarat se o ne. + +[* grunt-success.png *] + +Super, v adresari se nam objevil minifikovane verze, co ted s nima? + + +Prepinani verzi v latte +-------------------------- + +Pro vyvoj budeme chtit neminifikovane vicesouborove reseni a pro nasazeni na produkci budeme chtit zobrazovat minifikovanou verzi. + + +Jak toho docilit. Ja si definoval v neon.configu promenou ktera mi rika jakou verzi chci pouzit pripadne mam i jeji verzove pojmenovani (kvuli cache) + +*config.neon* + +/--neon +# +# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser! +# +# If you don't protect this directory from direct web access, anybody will be able to see your passwords. +# http://nette.org/security-warning +# +parameters: + site: # <--- + develMode: false # <--- + version: blackhawk # <--- + +php: + date.timezone: Europe/Prague + # zlib.output_compression: yes + + +nette: + application: + errorPresenter: Error + mapping: + *: App\*Module\Presenters\*Presenter + + session: + expiration: 14 days + + +services: + - App\Model\UserManager + - App\RouterFactory + router: @App\RouterFactory::createRouter +\-- + +Drobna uprava v basepresenteru aby se o techto parametrech dozvedela sablona, asi to neni nejcistsi reseni ale pro tento priklad nam to staci a nebudeme si to komplikovat. + +*BasePresenter.php* + +/--php +/** + * Base presenter for all application presenters. + */ +abstract class BasePresenter extends Nette\Application\UI\Presenter +{ + public function beforeRender() + { + parent::beforeRender(); + + $this->template->production = !$this->context->parameters['site']['develMode']; + $this->template->version = $this->context->parameters['site']['version']; + } +} +\-- + +a nasledna uprava v sablone *@layout.latte* + +/--html +{if $production} + + +{else} + + + + + + +{/if} +\-- + +a + +/--html +{if $production} + +{else} + + + + + +{/if} +\-- + +a ted uz by nase aplikace mela pouzivat minifikovane verze. + +[* grunt-final-sourcecode.png *] + +Cely projekt najdete na https://github.com/chemix/Nette-Grunt + + +{{tags: cookbook}} + +{{author: chemiX|3705}} diff --git a/pla/cs/homepage.texy b/pla/cs/homepage.texy index 6bfee0747e..543df42b68 100644 --- a/pla/cs/homepage.texy +++ b/pla/cs/homepage.texy @@ -164,6 +164,7 @@ Changelog a zkušenosti s přechodem mezi verzemi Tipy ==== | [Stažení sandboxu přes Composer |sandbox-composer] | Kuchařka +| [Minifikace js a css pomoci Gruntu |grunt-a-usemin] | Kuchařka Frameworky nad Nette === diff --git a/pla/en/grunt-with-usemin.texy b/pla/en/grunt-with-usemin.texy new file mode 100644 index 0000000000..2dcc16ee86 --- /dev/null +++ b/pla/en/grunt-with-usemin.texy @@ -0,0 +1,272 @@ +Nette and Grunt +=============== + + +Why this friendship? +-------------------- + +Because everyone can have only **one javascript** and **one stylesheet** file. In era of mobile internet, when every request is expensive, we don't want header like this (in better example) + +[* grunt-drupal.png *] + +What we want is that one minified javascript file and one minified file with stylesheets. I have got the best experience with Grunt and his great garden of plugins. I will show you simple example how to automate this task. + + +What we need. +------------- + +Clean installation of Nette sandbox http://github.com/nette/sandbox and working Grunt http://gruntjs.com. + + +.[tip] +Grunt is JavaScript task runner. It’s similar to Make or Ant but written in JavaScript. Grunt has a lot of interesting plugins for better fronted development, but not only for frontend. Look at gruntjs.com/plugins. + +How to install grunt-cli: + +Grunt requires node.js in the latest version and a package manager npm http://nodejs.org. + +When we already have npm with node.js installed, we can install grunt-cli to global space. +`npm install -g grunt-cli` + +If everything works, after you run command `grunt --version` you should see something like this. + +[* grunt-version.png *] + + +Let's prepare working version of Nette Sandbox in ProjectGrunt folder. The best way how to do this, is by using composer. + +`composer create-project nette/sandbox ProjectGrunt` + +[* grunt-nette-sandbox-composer.png *] + + +Check folder content. + +[* grunt-folder.png *] + + + +After you configured web server and adjusted permission for log and temp folders (`chmod -R a+rw temp log`) sandbox clone should work. If it doesn't work, you should follow [Quick start | http://doc.nette.org/en/2.1/quickstart/getting-started] guide. + + + +Configuration +------------- + +Create file *package.json* in root folder. It contains list of node.js modules what we need to install (using npm). + +/-- +{ + "name": "ProjectGrunt", + "version": "1.0.0", + "devDependencies": { + "grunt": "~0.4.4", + "grunt-usemin": "~2.1.0", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-uglify": "~0.4.0", + "grunt-contrib-cssmin": "~0.9.0", + "grunt-nette-basepath": "~0.2.0" + } +} +\-- + +**grunt** - use latest version of Grunt + +**grunt-usemin** - plugin for analysing our templates and prepare blocks with files for the next processes + +**grunt-contrib-concat** - plugin for concatenation files + +**grunt-contrib-uglify** - plugin for javascript minification + +**grunt-contrib-cssmin** - plugin for css minification + +**grunt-nette-basepath** - plugin for removing latte variable {$basePath} from file paths + + +Install these dependencies `npm install` + +[* grunt-npm-install.png *] + +Create file *Gruntfile.coffee* in project root. You can use Gruntfile.js but I prefer Coffee for its expressiveness. + +/-- +module.exports = (grunt) -> + grunt.initConfig + useminPrepare: + html: ['app/templates/@layout.latte'] + options: + dest: '.' + + netteBasePath: + basePath: 'www' + options: + removeFromPath: ['app/templates/'] + + # These plugins provide necessary tasks. + grunt.loadNpmTasks 'grunt-contrib-concat' + grunt.loadNpmTasks 'grunt-contrib-uglify' + grunt.loadNpmTasks 'grunt-contrib-cssmin' + grunt.loadNpmTasks 'grunt-usemin' + grunt.loadNpmTasks 'grunt-nette-basepath' + + # Default task. + grunt.registerTask 'default', [ + 'useminPrepare' + 'netteBasePath' + 'concat' + 'uglify' + 'cssmin' + ] +\-- + +This includes definition of all tasks that will be loaded. And then it will be specified defaul main task which is run after command `grunt` and configuration for tasks useminPrepare and netteBasePath. For more information how plugin Usemin works visit https://github.com/yeoman/grunt-usemin. + +In our case, we check config of netteBasePath task, where we said that basePath folder is in folder www, because Usemin plugin add to path folder, where file is located. We need to remove this path app/templates. + +.[error] +if you are running grunt under windows, this setting must be in windows style +/-- +removeFromPath: ['app\\templates\\'] +\-- +(I know this bug, and I will fix it later) + + +Run minification +----------------- + +Now we can run `grunt` , but we got this error, because we don’t have blocks for usemin task in our template + +[* grunt-usemin-error.png *] + +So we add these block to our template. In @layout.latte file we find classic javascript and css including and wrap it to build blocks. + +/--html + + + + + + +\-- + +and + +/--html + + + + + +\-- + +and now `grunt` looks for block definitions and prepares files for next tasks. + +[* grunt-success.png *] + +Great! Now we have minified files in folders, what is next? + + +Version switching in Latte +-------------------------- + +For devel version we want uncompressed files, but for production we want use minified version. + +How can we do this? I use configuration in neon.config where I define what version want to use and second config for version name to solve cache problems + +*config.neon* + +/--neon +# +# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser! +# +# If you don't protect this directory from direct web access, anybody will be able to see your passwords. +# http://nette.org/security-warning +# +parameters: + site: # <--- + develMode: false # <--- + version: blackhawk # <--- + +php: + date.timezone: Europe/Prague + # zlib.output_compression: yes + + +nette: + application: + errorPresenter: Error + mapping: + *: App\*Module\Presenters\*Presenter + + session: + expiration: 14 days + + +services: + - App\Model\UserManager + - App\RouterFactory + router: @App\RouterFactory::createRouter +\-- + +Update in BasePresenter so that templates know about these variables. Maybe it’s not the best solution, but good enough for this example. + +*BasePresenter.php* + +/--php +/** + * Base presenter for all application presenters. + */ +abstract class BasePresenter extends Nette\Application\UI\Presenter +{ + public function beforeRender() + { + parent::beforeRender(); + + $this->template->production = !$this->context->parameters['site']['develMode']; + $this->template->version = $this->context->parameters['site']['version']; + } +} +\-- + +and update *@layout.latte* + +/--html +{if $production} + + +{else} + + + + + + +{/if} +\-- + +and + +/--html +{if $production} + +{else} + + + + + +{/if} +\-- + +and now our application uses minified version + +[* grunt-final-sourcecode.png *] + +You can find whole example on github https://github.com/chemix/Nette-Grunt + + + + +{{tags: cookbook}} + +{{author: chemiX|3705}} diff --git a/pla/en/homepage.texy b/pla/en/homepage.texy index 0647fba628..ab26227091 100644 --- a/pla/en/homepage.texy +++ b/pla/en/homepage.texy @@ -52,6 +52,11 @@ AJAX | [Dependent form select with AJAX] | [Simple ajax example] + +Tips, Tools +=== +| [Grunt with usemin] + /---comment Dependency Injection and environment configuration === diff --git a/pla/files/grunt-drupal.png b/pla/files/grunt-drupal.png new file mode 100644 index 0000000000..e819d116cb Binary files /dev/null and b/pla/files/grunt-drupal.png differ diff --git a/pla/files/grunt-final-sourcecode.png b/pla/files/grunt-final-sourcecode.png new file mode 100644 index 0000000000..ca1a39baaa Binary files /dev/null and b/pla/files/grunt-final-sourcecode.png differ diff --git a/pla/files/grunt-folder.png b/pla/files/grunt-folder.png new file mode 100644 index 0000000000..93ff1e1541 Binary files /dev/null and b/pla/files/grunt-folder.png differ diff --git a/pla/files/grunt-nette-sandbox-composer.png b/pla/files/grunt-nette-sandbox-composer.png new file mode 100644 index 0000000000..db3b09748b Binary files /dev/null and b/pla/files/grunt-nette-sandbox-composer.png differ diff --git a/pla/files/grunt-npm-install.png b/pla/files/grunt-npm-install.png new file mode 100644 index 0000000000..bb45c79516 Binary files /dev/null and b/pla/files/grunt-npm-install.png differ diff --git a/pla/files/grunt-success.png b/pla/files/grunt-success.png new file mode 100644 index 0000000000..b2dc3ca3c0 Binary files /dev/null and b/pla/files/grunt-success.png differ diff --git a/pla/files/grunt-usemin-error.png b/pla/files/grunt-usemin-error.png new file mode 100644 index 0000000000..fd6c55210c Binary files /dev/null and b/pla/files/grunt-usemin-error.png differ diff --git a/pla/files/grunt-version.png b/pla/files/grunt-version.png new file mode 100644 index 0000000000..3ee7121156 Binary files /dev/null and b/pla/files/grunt-version.png differ