How to implement LESS css with magento?
سؤال
I want to use LESS CSS processing for theme development. Normally to implement LESS processor all you need to do is to add following lines to <head>
tag in your html
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="less.js" type="text/javascript"></script>
In Magento I tried to add following line to my local.xml file with no luck
<action method="addItem"><type>skin_css</type><name>css/custom.less</name></action>
This is so because LESS requires rel attribute to be rel="stylesheet/less"
, but magento obviously adds just rel="stylesheet"
with addItem method.
I also tried to overwrite rel tag with <param>rel="stylesheet/less"</param>
, but again with no result. Is there any workaround ? or any other solutions out there?
BTW. I did also find this this plugin, but this also did nothing.
المحلول
I know this is what they call 'hack', but it solved my problem. After all it is only for development. I will compile normal css file later and remove less.js.
So the solution is:
Add following lines to your local.xml file:
<action method="removeItem"><type>skin_css</type><name>css/styles.css</name></action><!-- remove main stylesheet -->
<action method="addItem"><type>skin_css</type><name>css/styles.less</name><params>id="less"</params></action><!-- add you less file with id="less" -->
<action method="addItem"><type>skin_js</type><name>js/less.js</name></action><!-- include less compiler -->
and the 'hack' part is to open your less.js file and search for rel==="stylesheet/less"
and change it to id==="less"
This solution is meant only for development. If you're done with less, compile it to css and remove those 3 lines from your local.xml
or if you are and you should, developing in localhost, you can just keep those 3 lines in your localhost and not in server install ;) This way all you have to do after finishing edit, is open cmd, compile css and upload it to server. Happy coding :)
نصائح أخرى
Erfan's solution is good enough. But as ruuter said, you need to keep a correct order when include less files. In that case you can add both css and js files via setText method() :
<reference name="head">
<block type="core/text" name="lesscss">
<action method="setText">
<less>
<![CDATA[
<link rel="stylesheet/less" type="text/css" href="path/to/skin/custom.less" media="all" />
<script type="text/javascript" src="/path/to/skin/js/less.js"></script>
]]>
</less>
</action>
</block>
</reference>
Agree, it's not the best solution. However, it's working.
Instead of hacking LESS, another option is to add something like the following to your local.xml:
<reference name="head">
<block type="core/text" name="lesscss">
<action method="setText">
<css><![CDATA[<link rel="stylesheet/less" type="text/css" href="path/to/skin/custom.less" media="all" />]]></css>
</action>
</block>
</reference>
IMO, the best solution is to create a module that extends the Mage_Page_Block_Html_Head class
and adds a addLess method or something, and also adds configuration in the backend: "enable live mode". Hmm, the module you linked looks interesting actually, if you have time you should look into why it's not working for you...
A less savvy solution would be to place the script tag into the "Miscellaneous Scripts" area of System > Config > Design. This allows editing via CMS and you can configure it to be managed at differing store views. Not terribly elegant, but allows you the flexibility to add/remove in a dev environment at-will.
I would be careful using less.js in a production environment. Each request to a page will require a new compilation of the less.css file. A more sustainable route is to look at your deployment, When you push a change live / development have the deployment compile the less into css.
That way you can minimize css, cache and help reduce load time.
To include less.css with rel='stylesheet/less"
file in local.xml, addLinkRel()
method of Mage_Page_Block_Html_Head
can be used,
<action method="addLinkRel">
<rel>stylesheet/less</rel>
<href>path/to/less/file</href>
</action>
In my case, I included bootstrap.less in header, and less.js using setText()
so that the JS always includes after the less file. And it seems to work. My complete xml for the head is:
<reference name="head">
<action method="addLinkRel">
<rel>stylesheet/less</rel>
<href>skin/frontend/magentodev/default/css/bootstrap/less/bootstrap.less</href>
</action>
<block type="core/text" name="less.css">
<action method="setText">
<text><![CDATA[<script type="text/javascript" src="skin/frontend/magentodev/default/js/less/less-1.5.0.min.js"/>]]></text>
</action>
</block>
</reference>
Update:
There was a problem using addLinkRel()
method, because it needs a full url(I suppose) as arguement for <href></href>
tags. So I finally ended up my local.xml
look like this:
<reference name="head">
<action method="addItem"><type>skin_css</type><name>css/bootstrap/less/bootstrap.less</name><params>class="stylesheet-less"</params></action>
<action method="addItem"><type>skin_css</type><name>css/magentodev.less</name><params>class="stylesheet-less"</params></action>
<block type="core/text" name="stylesheet-less">
<action method="setText">
<text><![CDATA[<script type="text/javascript">jQuery('.stylesheet-less').attr('rel', 'stylesheet/less');</script>]]></text>
</action>
</block>
</reference>
<reference name="after_body_start">
<block type="core/template" name="global.js" template="/page/html/globalJs.phtml" output="toHtml"/>
</reference>
Content of globalJs.phtml
:
<?php
/*
* Base Theme
*/
?>
<script src="<?php echo $this->getSkinUrl('js/less/less-1.5.0.min.js')?>" type="text/javascript"></script>
And Yes, this setup should be used for development. Not for Production server.