If you built a couple of block templates, you’ll probably have had some nasty CSS code. Quite often you’ll have block specific options, a background color for example, which has to change the CSS file. You can easily do that, no doubt, just use addHeaderItem or put a style tag in your view.php. The block controller code might look like this:
1 2 3 | public function on_page_view() { $this->addHeaderItem('<style type="text/css">#my-block-' . $this->bID . ' { background: ' . $this->backgroundColor . '; }</style>'); } |
In most cases you’ll find situations where the developer mixed a code like shown above with an external CSS file.
That certainly works but it’s usually much more elegant to keep all the block related CSS rules in a single file. We can use the great LESS language to achieve a much more elegant solution. Wouldn’t it be great if you could put all the CSS rules in a file like this:
1 2 3 4 5 6 | #my-block@{bID} { background: @backgroundColor; display: block; width: 100px; height: 100px; } |
That’s possible, it just takes a bit more code. You’ll need lessphp available here http://leafo.net/lessphp/. In your block controller, you can use a method like this to compile a LESS file like the one shown above into a static CSS with all variables replaced on the fly if required. Here’s the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public function on_page_view() { // get current block template $template = $this->getCurrentTemplate(); $bv = new BlockView(); $bv->setController($this); $bv->setBlockObject($this->getBlockObject()); // build path to less file $blockPath = $bv->getBlockPath(); if ($template == '') { $blockTemplateLessPath = $blockPath . DIRECTORY_SEPARATOR . 'view.less'; } else { $blockTemplateLessPath = $blockPath . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . 'view.less'; } // there's a less file, check if we have to rebuild it if (file_exists($blockTemplateLessPath)) { $lessFileHash = md5($blockTemplateLessPath . $this->bID . filemtime($blockTemplateLessPath)); $cacheFile = DIR_FILES_CACHE . '/my-block-' . $lessFileHash . '.css'; // cache file doesn't exist, rebuild it if (!file_exists($cacheFile)) { $lessc = Loader::library('3rdparty/lessc.inc', 'my_block'); $lessc = new lessc(); $lessc->setVariables( array( 'backgroundColor' => $this->backgroundColor, 'bID' => $this->bID ) ); $lessc->compileFile($blockTemplateLessPath, $cacheFile); } // include generated css file $this->addHeaderItem('<link rel="stylesheet type="text/css" href="' . REL_DIR_FILES_CACHE . '/cover-picture-' . $lessFileHash . '.css' . '"/>'); } |
If these instructions were a bit short, you can find a working example in one of my github repositories, check this: https://github.com/Remo/concrete5-cover-picture/blob/master/blocks/cover_picture/controller.php#L43-L81.
I hope this helps you to clean up your code!
1 Comment
[…] followed the information here: http://www.codeblog.ch/2014/01/concrete5-use-less-files-for-block-templates/ and Remo’s code that it links to but getCurrentTemplate() does not exist on the […]