User tests: Successful: Unsuccessful:
Feature tracker: http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33415
This also fixes this issue:
http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33618
This pull request introduces some new JLayout
based features:
I have added the option to chain methods when possible. Now you can do:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
echo $renderer
->setClient(0)
->setComponent('com_categories')
->render($this->item->tags->itemTags);
Version 3.2 already supported suffixes but I created some improvements.
Now suffixes can be added dynamically with setSuffixes($suffixes)
method. Example:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
echo $renderer
->setComponent('com_content')
->setClient(1)
->setSuffixes(array('j25'))
->render($this->item->tags->itemTags);
Most extended suffixes use was for having different versions for Joomla 2.5 & Joomla 3.x. I've added an automatic mode that will load the default version suffixes:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
echo $renderer
->setSuffixes('autoversion')
->render($this->item->tags->itemTags);
Will automatically load this suffixes when executed on Joomla 3.2.3:
Suffixes: Array
(
[0] => j323
[1] => j32
[2] => j3
)
So it will search for a layout in this priority order:
Searching layout for: joomla/content/tags.j323.php
Searching layout for: joomla/content/tags.j32.php
Searching layout for: joomla/content/tags.j3.php
Searching layout for: joomla/content/tags.php
This is mainly intended to be used on classes that extend JLayoutFile
because sadly layouts are not available on Joomla 2.5.x series (they are included on FOF now).
For example an extended class running the same code on Joomla 2.5.18 will search layouts on:
Searching layout for: joomla/content/tags.j2518.php
Searching layout for: joomla/content/tags.j25.php
Searching layout for: joomla/content/tags.j2.php
Searching layout for: joomla/content/tags.php
As you can see is useful to have layout specific for a Joomla version.
This is an automatic suffix mode language oriented. Example:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
echo $renderer
->setSuffixes('autolanguage')
->render($this->item->tags->itemTags);
It will automatically add this suffixes when executed on a site with en-GB
language active.
Suffixes: Array
(
[0] => en-GB
[1] => en
[2] => ltr
)
So you can create a layout for:
Good examples would be addresses that are ordered differently on different languages or layouts specifics to RTL
(Right To Left) languages
Now JLayoutFile
also supports prefixes. This is mainly to group different prefixes under the same prefix. In the practice a prefix is a main folder that stores all that layouts. Example:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
echo $renderer
->setPrefixes('bootstrap3')
->render($this->item->tags->itemTags);
It will search layouts in this order when called from the article view:
Include Paths: Array
(
[0] => templates/protostar/html/layouts/com_content/bootstrap3
[1] => components/com_content/layouts/bootstrap3
[2] => templates/protostar/html/layouts/bootstrap3
[3] => layouts/bootstrap3
[4] => templates/protostar/html/layouts/com_content
[5] => components/com_content/layouts
[6] => templates/protostar/html/layouts
[7] => layouts
)
So for example if you are on a template that supports both bootstrap2 & bootstrap3 mode you can put in the layouts/bootstrap3 folder the specific layouts for bootstrap3.
When a layout is already searched in a specific list of include paths the final path is saved on cache. Next time the layout is searched in that list of include paths the cached path will be returned.
Now JLayoutFile
stores statistics about its use. To get the stats you have to use:
$stats = JLayoutFile::getStats();
It will return something like:
Array
(
[fileSearches] => 20
[fileSearchesCached] => 11
[fileSearchesSkipped] => 0
[times] => Array
(
[fileSearching] => 0.0028524398803711
[fileRendering] => 0.024386882781982
[/var/www/jcms3x/layouts/plugins/content/vote/vote.php] => 0.0019118785858154
[/var/www/jcms3x/layouts/joomla/content/blog_style_default_item_title.php] => 0.0065479278564453
[/var/www/jcms3x/layouts/joomla/content/icons.php] => 0.005518913269043
[/var/www/jcms3x/layouts/joomla/content/info_block/author.php] => 0.00033211708068848
[/var/www/jcms3x/layouts/joomla/content/info_block/category.php] => 0.0012009143829346
[/var/www/jcms3x/layouts/joomla/content/info_block/publish_date.php] => 0.00086474418640137
[/var/www/jcms3x/layouts/joomla/content/info_block/hits.php] => 0.0002598762512207
[/var/www/jcms3x/layouts/joomla/content/info_block/block.php] => 0.0072002410888672
[/var/www/jcms3x/layouts/joomla/content/intro_image.php] => 0.00026798248291016
)
[layoutsRendered] => Array
(
[/var/www/jcms3x/layouts/plugins/content/vote/vote.php] => 2
[/var/www/jcms3x/layouts/joomla/content/blog_style_default_item_title.php] => 2
[/var/www/jcms3x/layouts/joomla/content/icons.php] => 2
[/var/www/jcms3x/layouts/joomla/content/info_block/block.php] => 4
[/var/www/jcms3x/layouts/joomla/content/info_block/author.php] => 2
[/var/www/jcms3x/layouts/joomla/content/info_block/category.php] => 2
[/var/www/jcms3x/layouts/joomla/content/info_block/publish_date.php] => 2
[/var/www/jcms3x/layouts/joomla/content/info_block/hits.php] => 2
[/var/www/jcms3x/layouts/joomla/content/intro_image.php] => 2
)
)
All the stats in a single array.
$stats['fileSearches']
: Number of layout searches performed
$stats['fileSearchesCached']
: Number of layout searches returning cached paths
$stats['fileSearchesSkipped']
: Number of layout searches skipped because they share same instance with same params
$stats['times']
: Array containing different times tracked
$stats['times']['fileSearching']
: Total time spent searching layouts on file system
$stats['times']['fileRendering']
: Total time spent rendering layouts
$stats['times'][$path]
: System stores also time spent rendering each layout. This includes the global rendering time of rendering all appearences of this layout.
$stats['layoutsRendered']
: Array containing the list of layouts rendered (array key) and the times it has been rendered ( value).
In the previous versions you could not specify a list of include paths. The layout paths were always calculated automatically. Now you have total control over them
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
$renderer->setIncludePaths(
array(
JPATH_COMPONENT . '/layouts',
JPATH_SITE . '/layouts'
)
);
echo $renderer->render($this->item->tags->itemTags);
Will search for layouts on:
Include Paths: Array
(
[0] => /var/www/jcms3x/components/com_content/layouts
[1] => /var/www/jcms3x/layouts
)
Delete the include paths information
echo $renderer
->setIncludePaths(
array(
JPATH_COMPONENT . '/layouts',
JPATH_SITE . '/layouts'
)
)
->resetIncludePaths()
->addIncludePaths(
array(
JPATH_COMPONENT . '/layouts-new',
JPATH_SITE . '/layouts-new'
)
)
->render($this->item->tags->itemTags);
will search in this include paths:
Include Paths: Array
(
[0] => /var/www/jcms3x/components/com_content/layouts-new
[1] => /var/www/jcms3x/layouts-new
)
It will load the automatically calculated paths.
This adds the option for fields to specify requirements that will prevent the field from being loaded.
There are only 2 main requirements defined at this point:
Note: This adds the support but most of the fields will require to modify the geInput() method to add the $this->validateRequirements()
call. So don't expect it works on all fields out of the box. It should only work on labels and on text field.
A sample field definition:
<field
name="title"
type="text"
label="JGLOBAL_TITLE"
description="JFIELD_TITLE_DESC"
requires="multilanguage"
required="true"
/>
You can specify more than one requirement:
<field
name="title"
type="text"
label="JGLOBAL_TITLE"
description="JFIELD_TITLE_DESC"
requires="multilanguage,associations"
required="true"
/>
You can easily extend requirements for your field like:
/**
* Function to determine if field validates the requirements
*
* @return boolean
*/
protected function validateRequirements()
{
if (parent::validateRequirements())
{
$requires = explode(',', (string) $this->element['requires']);
if (in_array('myrequirement', $requires) && !MyHelper::validateRequirement())
{
return false;
}
}
return true;
}
This adds support to use JLayoutFile
to render form fields. This is added in JFormField
but it doesn't change most of the existing fields to ensure BC. So don't expect it to work out of the box on all the fields. Included fields are:
Now layouts can be defined inside fields setting the property $layout
:
/**
* Layout to render
*
* @var string
*/
protected $layout = 'joomla.form.field.list';
But they also can be overriden on form. Thanks to this we can save to create new fields when the logic to get the data is the same and only the logic to render it changes. Examples would be to load select2
on a field for example:
<field
name="show_title"
type="list"
class="chzn-color"
label="JGLOBAL_SHOW_TITLE_LABEL"
description="JGLOBAL_SHOW_TITLE_DESC"
layout="joomla.form.field.select2"
>
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="1">JSHOW</option>
<option value="0">JHIDE</option>
</field>
Or imagine that you have a layout to render a filed loading typeahead.js
field:
<field
name="title"
type="list"
label="JGLOBAL_TITLE"
description="JFIELD_TITLE_DESC"
layout="form.field.typeahead"
required="true"
/>
You can also set a specific layout for the label and layout prefixes/suffixes on your field class:
/**
* Layout to render the field label
*
* @var string
*/
protected $labelLayout = 'joomla.form.field.label';
/**
* Prefixes to use to render the field.
*
* @var array
*/
protected $layoutPrefixes = array();
/**
* Suffixes to use to render the field.
*
* @var array
*/
protected $layoutSuffixes = array();
or in your form XML file:
<field
name="show_title"
type="list"
class="chzn-color"
label="JGLOBAL_SHOW_TITLE_LABEL"
description="JGLOBAL_SHOW_TITLE_DESC"
label-layout="joomla.form.field.label2"
layout-prefixes="bootstrap3"
layout-suffixes="j25"
>
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="1">JSHOW</option>
<option value="0">JHIDE</option>
</field>
If you want to change the default paths or load your extended class instead of JLayoutFile
you can nor override the getRenderer method:
/**
* Get the layout used to render the field.
*
* @param string $layoutId Layout to render
* @param mixed $options Optional custom options to load. JRegistry or array format
*
* @return JLayoutFile The layout
*/
public function getRenderer($layoutId, $options = array())
{
$prefixes = !empty($this->element['layout-prefixes']) ? explode(',', $this->element['layout-prefixes']) : $this->layoutPrefixes;
$suffixes = !empty($this->element['layout-suffixes']) ? explode(',', $this->element['layout-suffixes']) : $this->layoutSuffixes;
$options = array_merge(array('prefixes' => $prefixes, 'suffixes' => $suffixes), $options);
return new JLayoutFile($layoutId, null, $options);
}
This gives a very flexible tool to developers.
Now in your plugin you can do something like:
return $this->getRenderer('default')->render(
array(
'context' => $context,
'row' => $row,
'params' => $params,
'page' => $page
)
);
It will search a default.php
layout on:
Include Paths: Array
(
[0] => /var/www/jcms3x/templates/protostar/html/layouts/plugins/content/vote
[1] => /var/www/jcms3x/layouts/plugins/content/vote
)
Note: All the plugins are still using the old hardcoded method. Only the plugin content/vote
has been converted for testing purposes.
Now the debug console shows all the information of the layouts loaded in the current page:
Required tests include:
Labels |
Labels |
Added:
?
|
Labels |
Labels |
I'll review travis errors tomorrow
I think you forgot to include the layout for the vote plugin? Vote doesn't show currently.
About the stats collecting. If I saw this correct you're doing that always? Wouldn't it make sense to only do that when debug is enabled? Otherwise we just generate overhead here for no reason.
About the prefix, I'm not sure I understand the intention here:
So for example if you are on a template that supports both bootstrap2 & bootstrap3 mode you can put in the layouts/bootstrap3 folder the specific layouts for bootstrap3.
As I understand it, the prefix (as well as suffixes, autolanguage and others) is set by the extension. How does that help a template? Or is that something a template could set globally?
Developers likely only add those if they provide different layouts themself. So most will not enable that. After all it's also a bit of a performance issue to look up ~15 override paths per layout (3 from autolanguage, 3 from autoversion, 7 from prefix plus the regular ones).
Writing this, I just wonder what exactly happens when we have both prefixes and suffixes set. Do they multiplicate? Then that would make the above ~42 (7 prefix * 6 suffix) include paths to look up... That's makes be a bit feared right now.
Generally speaking, while I like what you did here, I fear this PR got a bit big which makes it harder to test. Especially since there are so many places one would have to test things. If you could for example split it up into a part for the basic enhancement (maybe with the plugin) and another for the JForm part, that would help. If the JForm one does depend on the basic one, it may be better to do it incrementally.
Title |
|
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2014-03-04 09:50:52 |
Would we be able to integrate into the JForm class a method to add a prefix/suffix to the layouts for all form fields? So if I want to say load bootstrap 2/3 classes or even frameworky. I can load that for all fields in the form instead of having to override the layout path for each individual field?
Just to be an arse :D
Sorry I forgot to answer before closing the PR. Thanks for checking it.
@Bakual :
I think you forgot to include the layout for the vote plugin? Vote doesn't show currently.
Yes. I forgot the vote layout. Thanks for pointing it. I added it before closing this to be sure I have all ready here.
About the stats collecting. If I saw this correct you're doing that always? Wouldn't it make sense to only do that when debug is enabled? Otherwise we just generate overhead here for no reason.
about the
It's not a overhead to store 10 vars (counters) in an array. There is no performance issue for having it enabled it just increases counters and get microtimes. Maybe in the future if the system ges complex it will make sense. I invite you to waste your time doing performance tests.
About prefixes, suffixes: they are there for anybody that wants to use them. Of course you have to use the tools in a good way. That's the main reason to have now the layouts debug. The caching system will also help. I'll appreciate that the next time I propose something (with the tools to test it) you waste your time testing it before suggesting issues.
Generally speaking, while I like what you did here, I fear this PR got a bit big which makes it harder to test. Especially since there are so many places one would have to test things. If you could for example split it up into a part for the basic enhancement (maybe with the plugin) and another for the JForm part, that would help. If the JForm one does depend on the basic one, it may be better to do it incrementally.
This is something that needed to go together. The system was done to be a first step into the right direction and to start using the tools in the right way at the same time. 3.3 release was next week and you knew it.
I know it's not something easy to test. It wasn't to code and double check it. That's why I closed the PR. I'm not ready to rush during a week to explain why I use !empty()
or discuss what should go inside a layout or not. Not prepared for a full week like that to get this merged. It's quite unmotivating to talk about the finger when it's pointing to a bigger thing.
I have lost a lot of sleeping time to get this done. I won't lose more.
@wilsonge I faced that problem but I'm not sure modifying JForm is a good move. Probably the best move here would be to search the way to allow form XML overriding. This will solve this and many other issues.
Status | Closed | ⇒ | New |
@phproberto I certainly didn't want to demotivate you and I am sorry if it came across like this.
It's hard to test something when you don't know the ins and outs of the code involved.
To test this I probably have to invest a whole evening. I'm happy to do that because I think it's a good move. But I would like to understand it prior to testing. That's why I asked the questions based on looking at your description (and briefly code) to get it right.
I've sent a new commit to add layout support for views. It's intended to replace the old system (template folders are the same). So we cannot use it on core components for now because BC but we can start using it for new views and start encouraging extension developers to use it.
To switch to the new system you have to replace in your view display
method:
parent::display($tpl);
with:
echo $this->getRenderer('default')->render(
array(
'items' => $this->items,
'pagination' => $this->pagination,
'state' => $this->state,
'user' => $this->user
)
);
I removed the new mvc view path. For classes that use the view
folder they can override the getRenderer method.
Branch rebased
OK awesome :) I've been really busy today but I'll have this tested tomorrow (afternoon/evening) :D
To fully ensure BC I will review that all the fields that extend JFormFieldList work.
I converted getRenderer
view method to public to be able to render a view inside another view (pseudo-HMVC)
Rebased vs latest staging to resolve conflicts
Roberto - somethings weird. I can't seem to use pagination in the article manager (it works in a clean 3.2.3 install so not sure what the hell is going on) - I don't understand at all why your changes would affect that specific pagination though :/
Further to the above it also appears in banners (and is related to the search tools - as these are the two components where search tools appears to be used) - it would appear that everytime to press anything in pagination for some reason unpublish is being selected in the search tools - even when it's not open - god knows why
Ahh I see. I've just hit a PR into your branch that starts to deal with the unit test failures. Not sure how you want to deal with the layout changes - whether in the JLayout or in the unit tests themselves. Updates look good on a quick run through in localhost but will test more thoroughly tomorrow as pretty tired right now :)
I'm not sure neither but maybe in the unit tests is better no? To compare field properties
Hmm probably. Not quite sure how we'd go about comparing the properties though other than doing some nasty preg_replace checks or something like that :/ Will have a ponder. At least the unit test failures now are just due to the spacings in the fields
In the meantime I've found an absolutely critical bug. See my PR :P
OK :) Looks perfect to me!
To get this on 3.3 we have to fix the unit tests and get this tested by more people in next 1-2 days
I can do the tests. There's already 1 other test on the tracker and I can hopefully get 1 more to test. 3 testers + passing tests should be enough to set ready for review
Test done successfully.
Rebased again
Tested the suffix thing, struggled a bit about the setSuffixes('autoversion') and setSuffixes('auto language'), because one overwrites the other, I had expected that using both results in something like:
file.en.j3.php
file.lrt.j3.php
....
It's complicated but maybe worth thinking about, maybe for one of the next version something like "autoall".
Thanks Robert!
I thought about mixing both but that would be 4 x 3 = 12 file searches. I agree it can be a good thing in next versions but for now I'd ensure that the system is stable with current changes and incoming layout conversions.
PR to fix the tests is awaiting you :)
@phproberto great job as always :) I've noticed that you've added a renderData
method. May be it is logical to change render
to renderData
in the helper?
mmm sorry @b2z I forgot to comment that feature :D
The renderData
is intended to be the final rendering method (programmaticaly talking). It adds some feature commonly used on other rendering systems:
$renderer = new JLayoutFile('joomla.content.tags', null, array('debug' => true));
$calculatedVar = 105 / 5;
$renderer->assign('myVar', $calculatedVar);
echo $renderer->renderData(array('anotherVar', 145));
The main problem with this is that it expects that you always pass an array to the renderer and that's not BC because we now have places were we are passing view instances directly for example.
That's why I had to create a new method.
The helper is intended to be a fast call to load a layout and render it with the given data. So you can still use the old call. I think we can standarize the calls for 4.0 but not before.
I'll add this documentation to the PR text. Thanks for pointing it.
P.S.: I rebased it and fixed some conflicts with current master
@phproberto thanks, now it is clear!
@phproberto
After applying the patch (setup: 3.3beta2, this patch with com_patchtester) get this error:
Fatal error: Cannot redeclare JFormField::validateRequirements() in /www/htdocs/custompath/libraries/joomla/form/field.php on line 1005
E.g. by accessing the menu item edit page at the Backend:
http://www.example.org/administrator/index.php?option=com_menus&view=items&menutype=usermenu
Or Mass Mail Users view:
http://www.example.org/administrator/index.php?option=com_users&view=mail
After turn this into a comment line The views will work.
https://github.com/phproberto/joomla-cms/blob/layouts-field/libraries/joomla/form/field.php#L1000-1024
@phproberto tests the debug feature is ok. Looks very good here, like it
Also User field look good here. (Tested at the com_content article view at the created_by option)
Also tested some backend views with some fields. I have not see that any one failed.
Good work here
Description | <p>Feature tracker: <a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33415">http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33415</a></p> <p>This also fixes this issue:<br><a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33618">http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33618</a></p> <p>This pull request introduces some new <code>JLayout</code> based features:</p> <h1>JLayout improvements</h1> <h2>1. Chainable methods</h2> <p>I have added the option to chain methods when possible. Now you can do:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setClient</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">-></span><span class="na">setComponent</span><span class="p">(</span><span class="s1">'com_categories'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <h2>2. Suffixes improvements</h2> <p>Version 3.2 already supported suffixes but I created some improvements.</p> <h3>2.1 Add suffixes dynamically</h3> <p>Now suffixes can be added dynamically with <code>setSuffixes($suffixes)</code> method. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setComponent</span><span class="p">(</span><span class="s1">'com_content'</span><span class="p">)</span> <span class="o">-></span><span class="na">setClient</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'j25'</span><span class="p">))</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <h3>2.2 Automatic version suffixes</h3> <p>Most extended suffixes use was for having different versions for Joomla 2.5 & Joomla 3.x. I've added an automatic mode that will load the default version suffixes:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="s1">'autoversion'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>Will automatically load this suffixes when executed on Joomla 3.2.3:</p> <div class="highlight highlight-php"><pre><span class="nx">Suffixes</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j323</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j32</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j3</span> <span class="p">)</span> </pre></div> <p>So it will search for a layout in this priority order:</p> <pre><code>Searching layout for: joomla/content/tags.j323.php Searching layout for: joomla/content/tags.j32.php Searching layout for: joomla/content/tags.j3.php Searching layout for: joomla/content/tags.php </code></pre> <p>This is mainly intended to be used on classes that extend <code>JLayoutFile</code> because sadly layouts are not available on Joomla 2.5.x series (they are included on FOF now). </p> <p>For example an extended class running the same code on Joomla 2.5.18 will search layouts on:</p> <pre><code>Searching layout for: joomla/content/tags.j2518.php Searching layout for: joomla/content/tags.j25.php Searching layout for: joomla/content/tags.j2.php Searching layout for: joomla/content/tags.php </code></pre> <p>As you can see is useful to have layout specific for a Joomla version.</p> <h3>2.3 Automatic language suffixes</h3> <p>This is an automatic suffix mode language oriented. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="s1">'autolanguage'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>It will automatically add this suffixes when executed on a site with <code>en-GB</code> language active.</p> <div class="highlight highlight-php"><pre><span class="nx">Suffixes</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">en</span><span class="o">-</span><span class="nx">GB</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">en</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">ltr</span> <span class="p">)</span> </pre></div> <p>So you can create a layout for:</p> <ul> <li>This specific locale</li> <li>This specific language</li> <li>This specific language direction</li> </ul><p>Good examples would be addresses that are ordered differently on different languages or layouts specifics to <code>RTL</code> (Right To Left) languages</p> <h2>3. Prefixes support</h2> <p>Now <code>JLayoutFile</code> also supports prefixes. This is mainly to group different prefixes under the same prefix. In the practice a prefix is a main folder that stores all that layouts. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setPrefixes</span><span class="p">(</span><span class="s1">'bootstrap3'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>It will search layouts in this order when called from the article view:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=></span> <span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">com_content</span> <span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=></span> <span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="o">=></span> <span class="nx">layouts</span> <span class="p">)</span> </pre></div> <p>So for example if you are on a template that supports both bootstrap2 & bootstrap3 mode you can put in the layouts/bootstrap3 folder the specific layouts for bootstrap3. </p> <h2>4. Cached file searches</h2> <p>When a layout is already searched in a specific list of include paths the final path is saved on cache. Next time the layout is searched in that list of include paths the cached path will be returned.</p> <h2>5. Statistics</h2> <p>Now <code>JLayoutFile</code> stores statistics about its use. To get the stats you have to use:</p> <div class="highlight highlight-php"><pre><span class="nv">$stats</span> <span class="o">=</span> <span class="nx">JLayoutFile</span><span class="o">::</span><span class="na">getStats</span><span class="p">();</span> </pre></div> <p>It will return something like:</p> <div class="highlight highlight-php"><pre><span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="nx">fileSearches</span><span class="p">]</span> <span class="o">=></span> <span class="mi">20</span> <span class="p">[</span><span class="nx">fileSearchesCached</span><span class="p">]</span> <span class="o">=></span> <span class="mi">11</span> <span class="p">[</span><span class="nx">fileSearchesSkipped</span><span class="p">]</span> <span class="o">=></span> <span class="mi">0</span> <span class="p">[</span><span class="nx">times</span><span class="p">]</span> <span class="o">=></span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="nx">fileSearching</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0028524398803711</span> <span class="p">[</span><span class="nx">fileRendering</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.024386882781982</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span><span class="o">/</span><span class="nx">vote</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0019118785858154</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">blog_style_default_item_title</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0065479278564453</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">icons</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.005518913269043</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">author</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00033211708068848</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">category</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0012009143829346</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">publish_date</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00086474418640137</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">hits</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0002598762512207</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">block</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0072002410888672</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">intro_image</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00026798248291016</span> <span class="p">)</span> <span class="p">[</span><span class="nx">layoutsRendered</span><span class="p">]</span> <span class="o">=></span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span><span class="o">/</span><span class="nx">vote</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">blog_style_default_item_title</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">icons</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">block</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">4</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">author</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">category</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">publish_date</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">hits</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">intro_image</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">)</span> <span class="p">)</span> </pre></div> <p>All the stats in a single array. </p> <h3>5.1 Stats details</h3> <p><code>$stats['fileSearches']</code> : Number of layout searches performed<br><code>$stats['fileSearchesCached']</code> : Number of layout searches returning cached paths<br><code>$stats['fileSearchesSkipped']</code> : Number of layout searches skipped because they share same instance with same params<br><code>$stats['times']</code>: Array containing different times tracked<br><code>$stats['times']['fileSearching']</code>: Total time spent searching layouts on file system<br><code>$stats['times']['fileRendering']</code>: Total time spent rendering layouts<br><code>$stats['times'][$path]</code>: System stores also time spent rendering each layout. This includes the global rendering time of rendering all appearences of this layout.<br><code>$stats['layoutsRendered']</code>: Array containing the list of layouts rendered (array key) and the times it has been rendered ( value). </p> <h2>6. Better includepaths handling</h2> <p>In the previous versions you could not specify a list of include paths. The layout paths were always calculated automatically. Now you have total control over them</p> <h3>6.1 setIncludePaths</h3> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="nv">$renderer</span><span class="o">-></span><span class="na">setIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts'</span> <span class="p">)</span> <span class="p">);</span> <span class="k">echo</span> <span class="nv">$renderer</span><span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>Will search for layouts on:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">)</span> </pre></div> <h3>6.1 resetIncludePaths</h3> <p>Delete the include paths information</p> <div class="highlight highlight-php"><pre><span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts'</span> <span class="p">)</span> <span class="p">)</span> <span class="o">-></span><span class="na">resetIncludePaths</span><span class="p">()</span> <span class="o">-></span><span class="na">addIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts-new'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts-new'</span> <span class="p">)</span> <span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>will search in this include paths:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span><span class="o">-</span><span class="k">new</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">-</span><span class="k">new</span> <span class="p">)</span> </pre></div> <h3>6.2 loadDefaultIncludePaths</h3> <p>It will load the automatically calculated paths.</p> <h1>JFormField improvements</h1> <h2>1. Field requirements support</h2> <p>This adds the option for fields to specify requirements that will prevent the field from being loaded. </p> <p>There are only 2 main requirements defined at this point:</p> <ul> <li> <strong>multilanguage</strong> : Requires language filter is enabled</li> <li> <strong>associations</strong> : Requires language associations enabled</li> </ul><p><strong>Note:</strong> This adds the support but most of the fields will require to modify the geInput() method to add the <code>$this->validateRequirements()</code> call. So don't expect it works on all fields out of the box. It should only work on labels and on text field.</p> <p>A sample field definition:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">requires=</span><span class="s">"multilanguage"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can specify more than one requirement:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">requires=</span><span class="s">"multilanguage,associations"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can easily extend requirements for your field like:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Function to determine if field validates the requirements</span> <span class="sd"> *</span> <span class="sd"> * @return boolean</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="k">function</span> <span class="nf">validateRequirements</span><span class="p">()</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">parent</span><span class="o">::</span><span class="na">validateRequirements</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$requires</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="p">(</span><span class="nx">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'requires'</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="nb">in_array</span><span class="p">(</span><span class="s1">'myrequirement'</span><span class="p">,</span> <span class="nv">$requires</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">MyHelper</span><span class="o">::</span><span class="na">validateRequirement</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="k">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="k">true</span><span class="p">;</span> <span class="p">}</span> </pre></div> <h2>2. Layouts support</h2> <p>This adds support to use <code>JLayoutFile</code> to render form fields. This is added in <code>JFormField</code> but it doesn't change most of the existing fields to ensure BC. So don't expect it to work out of the box on all the fields. Included fields are:</p> <ul> <li>JFormFieldList</li> <li>JFormFieldUser </li> </ul><p>Now layouts can be defined inside fields setting the property <code>$layout</code>:</p> <div class="highlight highlight-php"><pre> <span class="sd">/**</span> <span class="sd"> * Layout to render</span> <span class="sd"> *</span> <span class="sd"> * @var string</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layout</span> <span class="o">=</span> <span class="s1">'joomla.form.field.list'</span><span class="p">;</span> </pre></div> <p>But they also can be overriden on form. Thanks to this we can save to create new fields when the logic to get the data is the same and only the logic to render it changes. Examples would be to load <code>select2</code> on a field for example:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"show_title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">class=</span><span class="s">"chzn-color"</span> <span class="na">label=</span><span class="s">"JGLOBAL_SHOW_TITLE_LABEL"</span> <span class="na">description=</span><span class="s">"JGLOBAL_SHOW_TITLE_DESC"</span> <span class="na">layout=</span><span class="s">"joomla.form.field.select2"</span> <span class="nt">></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">""</span><span class="nt">></span>JGLOBAL_USE_GLOBAL<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"1"</span><span class="nt">></span>JSHOW<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"0"</span><span class="nt">></span>JHIDE<span class="nt"></option></span> <span class="nt"></field></span> </pre></div> <p>Or imagine that you have a layout to render a filed loading <code>typeahead.js</code> field:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">layout=</span><span class="s">"form.field.typeahead"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can also set a specific layout for the label and layout prefixes/suffixes on your field class:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Layout to render the field label</span> <span class="sd"> *</span> <span class="sd"> * @var string</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$labelLayout</span> <span class="o">=</span> <span class="s1">'joomla.form.field.label'</span><span class="p">;</span> <span class="sd">/**</span> <span class="sd"> * Prefixes to use to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @var array</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layoutPrefixes</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="sd">/**</span> <span class="sd"> * Suffixes to use to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @var array</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layoutSuffixes</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> </pre></div> <p>or in your form XML file:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"show_title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">class=</span><span class="s">"chzn-color"</span> <span class="na">label=</span><span class="s">"JGLOBAL_SHOW_TITLE_LABEL"</span> <span class="na">description=</span><span class="s">"JGLOBAL_SHOW_TITLE_DESC"</span> <span class="na">label-layout=</span><span class="s">"joomla.form.field.label2"</span> <span class="na">layout-prefixes=</span><span class="s">"bootstrap3"</span> <span class="na">layout-suffixes=</span><span class="s">"j25"</span> <span class="nt">></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">""</span><span class="nt">></span>JGLOBAL_USE_GLOBAL<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"1"</span><span class="nt">></span>JSHOW<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"0"</span><span class="nt">></span>JHIDE<span class="nt"></option></span> <span class="nt"></field></span> </pre></div> <h2>3. Overridable getRenderer</h2> <p>If you want to change the default paths or load your extended class instead of <code>JLayoutFile</code> you can nor override the getRenderer method:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Get the layout used to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @param string $layoutId Layout to render</span> <span class="sd"> * @param mixed $options Optional custom options to load. JRegistry or array format</span> <span class="sd"> *</span> <span class="sd"> * @return JLayoutFile The layout</span> <span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">getRenderer</span><span class="p">(</span><span class="nv">$layoutId</span><span class="p">,</span> <span class="nv">$options</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$prefixes</span> <span class="o">=</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-prefixes'</span><span class="p">])</span> <span class="o">?</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-prefixes'</span><span class="p">])</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">layoutPrefixes</span><span class="p">;</span> <span class="nv">$suffixes</span> <span class="o">=</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-suffixes'</span><span class="p">])</span> <span class="o">?</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-suffixes'</span><span class="p">])</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">layoutSuffixes</span><span class="p">;</span> <span class="nv">$options</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'prefixes'</span> <span class="o">=></span> <span class="nv">$prefixes</span><span class="p">,</span> <span class="s1">'suffixes'</span> <span class="o">=></span> <span class="nv">$suffixes</span><span class="p">),</span> <span class="nv">$options</span><span class="p">);</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="nv">$layoutId</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$options</span><span class="p">);</span> <span class="p">}</span> </pre></div> <p>This gives a very flexible tool to developers.</p> <h1>Plugins improvements</h1> <h2>1. Layout support</h2> <p>Now in your plugin you can do something like:</p> <div class="highlight highlight-php"><pre><span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">getRenderer</span><span class="p">(</span><span class="s1">'default'</span><span class="p">)</span><span class="o">-></span><span class="na">render</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="s1">'context'</span> <span class="o">=></span> <span class="nv">$context</span><span class="p">,</span> <span class="s1">'row'</span> <span class="o">=></span> <span class="nv">$row</span><span class="p">,</span> <span class="s1">'params'</span> <span class="o">=></span> <span class="nv">$params</span><span class="p">,</span> <span class="s1">'page'</span> <span class="o">=></span> <span class="nv">$page</span> <span class="p">)</span> <span class="p">);</span> </pre></div> <p>It will search a <code>default.php</code> layout on:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span> <span class="p">)</span> </pre></div> <p><strong>Note:</strong> All the plugins are still using the old hardcoded method. Only the plugin <code>content/vote</code> has been converted for testing purposes.</p> <h2>2. Layouts information on debug</h2> <p>Now the debug console shows all the information of the layouts loaded in the current page:</p> <p><a href="https://camo.githubusercontent.com/2856d4aebcf013eba68d5f4592eb07d2bba80f6a/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313131393237322f323331373633342f64356163363163342d613335312d313165332d383534622d6163616336386536353638612e706e67" target="_blank"><img src="https://camo.githubusercontent.com/2856d4aebcf013eba68d5f4592eb07d2bba80f6a/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313131393237322f323331373633342f64356163363163342d613335312d313165332d383534622d6163616336386536353638612e706e67" alt="layouts-article-form" data-canonical-src="https://f.cloud.github.com/assets/1119272/2317634/d5ac61c4-a351-11e3-854b-acac68e6568a.png" style="max-width:100%;"></a></p> <h1>Testing</h1> <p>Required tests include:</p> <ul> <li>Check that all list fields are shown and work correctly (including tags and all other extending fields)</li> <li>Check that user field works correctly</li> <li>Check that when you enable the option to show votes on articles it's dispalyed correctly</li> <li>Make performance tests with & without this patch to ensure that layouts doesn't overload system.</li> <li>Common layout override tests with prefixes, suffixes, include paths....</li> </ul> | ⇒ | <p>Feature tracker: <a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33415">http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33415</a></p> <p>This also fixes this issue:<br><a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33618">http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=33618</a></p> <p>This pull request introduces some new <code>JLayout</code> based features:</p> <h1>JLayout improvements</h1> <h2>1. Chainable methods</h2> <p>I have added the option to chain methods when possible. Now you can do:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setClient</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">-></span><span class="na">setComponent</span><span class="p">(</span><span class="s1">'com_categories'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <h2>2. Suffixes improvements</h2> <p>Version 3.2 already supported suffixes but I created some improvements.</p> <h3>2.1 Add suffixes dynamically</h3> <p>Now suffixes can be added dynamically with <code>setSuffixes($suffixes)</code> method. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setComponent</span><span class="p">(</span><span class="s1">'com_content'</span><span class="p">)</span> <span class="o">-></span><span class="na">setClient</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'j25'</span><span class="p">))</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <h3>2.2 Automatic version suffixes</h3> <p>Most extended suffixes use was for having different versions for Joomla 2.5 & Joomla 3.x. I've added an automatic mode that will load the default version suffixes:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="s1">'autoversion'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>Will automatically load this suffixes when executed on Joomla 3.2.3:</p> <div class="highlight highlight-php"><pre><span class="nx">Suffixes</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j323</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j32</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">j3</span> <span class="p">)</span> </pre></div> <p>So it will search for a layout in this priority order:</p> <pre><code>Searching layout for: joomla/content/tags.j323.php Searching layout for: joomla/content/tags.j32.php Searching layout for: joomla/content/tags.j3.php Searching layout for: joomla/content/tags.php </code></pre> <p>This is mainly intended to be used on classes that extend <code>JLayoutFile</code> because sadly layouts are not available on Joomla 2.5.x series (they are included on FOF now). </p> <p>For example an extended class running the same code on Joomla 2.5.18 will search layouts on:</p> <pre><code>Searching layout for: joomla/content/tags.j2518.php Searching layout for: joomla/content/tags.j25.php Searching layout for: joomla/content/tags.j2.php Searching layout for: joomla/content/tags.php </code></pre> <p>As you can see is useful to have layout specific for a Joomla version.</p> <h3>2.3 Automatic language suffixes</h3> <p>This is an automatic suffix mode language oriented. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setSuffixes</span><span class="p">(</span><span class="s1">'autolanguage'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>It will automatically add this suffixes when executed on a site with <code>en-GB</code> language active.</p> <div class="highlight highlight-php"><pre><span class="nx">Suffixes</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">en</span><span class="o">-</span><span class="nx">GB</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">en</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">ltr</span> <span class="p">)</span> </pre></div> <p>So you can create a layout for:</p> <ul class="task-list"> <li>This specific locale</li> <li>This specific language</li> <li>This specific language direction</li> </ul><p>Good examples would be addresses that are ordered differently on different languages or layouts specifics to <code>RTL</code> (Right To Left) languages</p> <h2>3. Prefixes support</h2> <p>Now <code>JLayoutFile</code> also supports prefixes. This is mainly to group different prefixes under the same prefix. In the practice a prefix is a main folder that stores all that layouts. Example:</p> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setPrefixes</span><span class="p">(</span><span class="s1">'bootstrap3'</span><span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>It will search layouts in this order when called from the article view:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=></span> <span class="nx">layouts</span><span class="o">/</span><span class="nx">bootstrap3</span> <span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">com_content</span> <span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=></span> <span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=></span> <span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="o">=></span> <span class="nx">layouts</span> <span class="p">)</span> </pre></div> <p>So for example if you are on a template that supports both bootstrap2 & bootstrap3 mode you can put in the layouts/bootstrap3 folder the specific layouts for bootstrap3. </p> <h2>4. Cached file searches</h2> <p>When a layout is already searched in a specific list of include paths the final path is saved on cache. Next time the layout is searched in that list of include paths the cached path will be returned.</p> <h2>5. Statistics</h2> <p>Now <code>JLayoutFile</code> stores statistics about its use. To get the stats you have to use:</p> <div class="highlight highlight-php"><pre><span class="nv">$stats</span> <span class="o">=</span> <span class="nx">JLayoutFile</span><span class="o">::</span><span class="na">getStats</span><span class="p">();</span> </pre></div> <p>It will return something like:</p> <div class="highlight highlight-php"><pre><span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="nx">fileSearches</span><span class="p">]</span> <span class="o">=></span> <span class="mi">20</span> <span class="p">[</span><span class="nx">fileSearchesCached</span><span class="p">]</span> <span class="o">=></span> <span class="mi">11</span> <span class="p">[</span><span class="nx">fileSearchesSkipped</span><span class="p">]</span> <span class="o">=></span> <span class="mi">0</span> <span class="p">[</span><span class="nx">times</span><span class="p">]</span> <span class="o">=></span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="nx">fileSearching</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0028524398803711</span> <span class="p">[</span><span class="nx">fileRendering</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.024386882781982</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span><span class="o">/</span><span class="nx">vote</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0019118785858154</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">blog_style_default_item_title</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0065479278564453</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">icons</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.005518913269043</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">author</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00033211708068848</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">category</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0012009143829346</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">publish_date</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00086474418640137</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">hits</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0002598762512207</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">block</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.0072002410888672</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">intro_image</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mf">0.00026798248291016</span> <span class="p">)</span> <span class="p">[</span><span class="nx">layoutsRendered</span><span class="p">]</span> <span class="o">=></span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span><span class="o">/</span><span class="nx">vote</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">blog_style_default_item_title</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">icons</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">block</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">4</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">author</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">category</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">publish_date</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">info_block</span><span class="o">/</span><span class="nx">hits</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">[</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">joomla</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">intro_image</span><span class="o">.</span><span class="nx">php</span><span class="p">]</span> <span class="o">=></span> <span class="mi">2</span> <span class="p">)</span> <span class="p">)</span> </pre></div> <p>All the stats in a single array. </p> <h3>5.1 Stats details</h3> <p><code>$stats['fileSearches']</code> : Number of layout searches performed<br><code>$stats['fileSearchesCached']</code> : Number of layout searches returning cached paths<br><code>$stats['fileSearchesSkipped']</code> : Number of layout searches skipped because they share same instance with same params<br><code>$stats['times']</code>: Array containing different times tracked<br><code>$stats['times']['fileSearching']</code>: Total time spent searching layouts on file system<br><code>$stats['times']['fileRendering']</code>: Total time spent rendering layouts<br><code>$stats['times'][$path]</code>: System stores also time spent rendering each layout. This includes the global rendering time of rendering all appearences of this layout.<br><code>$stats['layoutsRendered']</code>: Array containing the list of layouts rendered (array key) and the times it has been rendered ( value). </p> <h2>6. Better includepaths handling</h2> <p>In the previous versions you could not specify a list of include paths. The layout paths were always calculated automatically. Now you have total control over them</p> <h3>6.1 setIncludePaths</h3> <div class="highlight highlight-php"><pre><span class="nv">$renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="s1">'joomla.content.tags'</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'debug'</span> <span class="o">=></span> <span class="k">true</span><span class="p">));</span> <span class="nv">$renderer</span><span class="o">-></span><span class="na">setIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts'</span> <span class="p">)</span> <span class="p">);</span> <span class="k">echo</span> <span class="nv">$renderer</span><span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>Will search for layouts on:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span> <span class="p">)</span> </pre></div> <h3>6.1 resetIncludePaths</h3> <p>Delete the include paths information</p> <div class="highlight highlight-php"><pre><span class="k">echo</span> <span class="nv">$renderer</span> <span class="o">-></span><span class="na">setIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts'</span> <span class="p">)</span> <span class="p">)</span> <span class="o">-></span><span class="na">resetIncludePaths</span><span class="p">()</span> <span class="o">-></span><span class="na">addIncludePaths</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="nx">JPATH_COMPONENT</span> <span class="o">.</span> <span class="s1">'/layouts-new'</span><span class="p">,</span> <span class="nx">JPATH_SITE</span> <span class="o">.</span> <span class="s1">'/layouts-new'</span> <span class="p">)</span> <span class="p">)</span> <span class="o">-></span><span class="na">render</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">item</span><span class="o">-></span><span class="na">tags</span><span class="o">-></span><span class="na">itemTags</span><span class="p">);</span> </pre></div> <p>will search in this include paths:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">components</span><span class="o">/</span><span class="nx">com_content</span><span class="o">/</span><span class="nx">layouts</span><span class="o">-</span><span class="k">new</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">-</span><span class="k">new</span> <span class="p">)</span> </pre></div> <h3>6.2 loadDefaultIncludePaths</h3> <p>It will load the automatically calculated paths.</p> <h1>JFormField improvements</h1> <h2>1. Field requirements support</h2> <p>This adds the option for fields to specify requirements that will prevent the field from being loaded. </p> <p>There are only 2 main requirements defined at this point:</p> <ul class="task-list"> <li> <strong>multilanguage</strong> : Requires language filter is enabled</li> <li> <strong>associations</strong> : Requires language associations enabled</li> </ul><p><strong>Note:</strong> This adds the support but most of the fields will require to modify the geInput() method to add the <code>$this->validateRequirements()</code> call. So don't expect it works on all fields out of the box. It should only work on labels and on text field.</p> <p>A sample field definition:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">requires=</span><span class="s">"multilanguage"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can specify more than one requirement:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">requires=</span><span class="s">"multilanguage,associations"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can easily extend requirements for your field like:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Function to determine if field validates the requirements</span> <span class="sd"> *</span> <span class="sd"> * @return boolean</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="k">function</span> <span class="nf">validateRequirements</span><span class="p">()</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">parent</span><span class="o">::</span><span class="na">validateRequirements</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$requires</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="p">(</span><span class="nx">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'requires'</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="nb">in_array</span><span class="p">(</span><span class="s1">'myrequirement'</span><span class="p">,</span> <span class="nv">$requires</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">MyHelper</span><span class="o">::</span><span class="na">validateRequirement</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="k">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="k">true</span><span class="p">;</span> <span class="p">}</span> </pre></div> <h2>2. Layouts support</h2> <p>This adds support to use <code>JLayoutFile</code> to render form fields. This is added in <code>JFormField</code> but it doesn't change most of the existing fields to ensure BC. So don't expect it to work out of the box on all the fields. Included fields are:</p> <ul class="task-list"> <li>JFormFieldList</li> <li>JFormFieldUser </li> </ul><p>Now layouts can be defined inside fields setting the property <code>$layout</code>:</p> <div class="highlight highlight-php"><pre> <span class="sd">/**</span> <span class="sd"> * Layout to render</span> <span class="sd"> *</span> <span class="sd"> * @var string</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layout</span> <span class="o">=</span> <span class="s1">'joomla.form.field.list'</span><span class="p">;</span> </pre></div> <p>But they also can be overriden on form. Thanks to this we can save to create new fields when the logic to get the data is the same and only the logic to render it changes. Examples would be to load <code>select2</code> on a field for example:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"show_title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">class=</span><span class="s">"chzn-color"</span> <span class="na">label=</span><span class="s">"JGLOBAL_SHOW_TITLE_LABEL"</span> <span class="na">description=</span><span class="s">"JGLOBAL_SHOW_TITLE_DESC"</span> <span class="na">layout=</span><span class="s">"joomla.form.field.select2"</span> <span class="nt">></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">""</span><span class="nt">></span>JGLOBAL_USE_GLOBAL<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"1"</span><span class="nt">></span>JSHOW<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"0"</span><span class="nt">></span>JHIDE<span class="nt"></option></span> <span class="nt"></field></span> </pre></div> <p>Or imagine that you have a layout to render a filed loading <code>typeahead.js</code> field:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">label=</span><span class="s">"JGLOBAL_TITLE"</span> <span class="na">description=</span><span class="s">"JFIELD_TITLE_DESC"</span> <span class="na">layout=</span><span class="s">"form.field.typeahead"</span> <span class="na">required=</span><span class="s">"true"</span> <span class="nt">/></span> </pre></div> <p>You can also set a specific layout for the label and layout prefixes/suffixes on your field class:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Layout to render the field label</span> <span class="sd"> *</span> <span class="sd"> * @var string</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$labelLayout</span> <span class="o">=</span> <span class="s1">'joomla.form.field.label'</span><span class="p">;</span> <span class="sd">/**</span> <span class="sd"> * Prefixes to use to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @var array</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layoutPrefixes</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="sd">/**</span> <span class="sd"> * Suffixes to use to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @var array</span> <span class="sd"> */</span> <span class="k">protected</span> <span class="nv">$layoutSuffixes</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> </pre></div> <p>or in your form XML file:</p> <div class="highlight highlight-xml"><pre><span class="nt"><field</span> <span class="na">name=</span><span class="s">"show_title"</span> <span class="na">type=</span><span class="s">"list"</span> <span class="na">class=</span><span class="s">"chzn-color"</span> <span class="na">label=</span><span class="s">"JGLOBAL_SHOW_TITLE_LABEL"</span> <span class="na">description=</span><span class="s">"JGLOBAL_SHOW_TITLE_DESC"</span> <span class="na">label-layout=</span><span class="s">"joomla.form.field.label2"</span> <span class="na">layout-prefixes=</span><span class="s">"bootstrap3"</span> <span class="na">layout-suffixes=</span><span class="s">"j25"</span> <span class="nt">></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">""</span><span class="nt">></span>JGLOBAL_USE_GLOBAL<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"1"</span><span class="nt">></span>JSHOW<span class="nt"></option></span> <span class="nt"><option</span> <span class="na">value=</span><span class="s">"0"</span><span class="nt">></span>JHIDE<span class="nt"></option></span> <span class="nt"></field></span> </pre></div> <h2>3. Overridable getRenderer</h2> <p>If you want to change the default paths or load your extended class instead of <code>JLayoutFile</code> you can nor override the getRenderer method:</p> <div class="highlight highlight-php"><pre><span class="sd">/**</span> <span class="sd"> * Get the layout used to render the field.</span> <span class="sd"> *</span> <span class="sd"> * @param string $layoutId Layout to render</span> <span class="sd"> * @param mixed $options Optional custom options to load. JRegistry or array format</span> <span class="sd"> *</span> <span class="sd"> * @return JLayoutFile The layout</span> <span class="sd"> */</span> <span class="k">public</span> <span class="k">function</span> <span class="nf">getRenderer</span><span class="p">(</span><span class="nv">$layoutId</span><span class="p">,</span> <span class="nv">$options</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span> <span class="p">{</span> <span class="nv">$prefixes</span> <span class="o">=</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-prefixes'</span><span class="p">])</span> <span class="o">?</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-prefixes'</span><span class="p">])</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">layoutPrefixes</span><span class="p">;</span> <span class="nv">$suffixes</span> <span class="o">=</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-suffixes'</span><span class="p">])</span> <span class="o">?</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">element</span><span class="p">[</span><span class="s1">'layout-suffixes'</span><span class="p">])</span> <span class="o">:</span> <span class="nv">$this</span><span class="o">-></span><span class="na">layoutSuffixes</span><span class="p">;</span> <span class="nv">$options</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'prefixes'</span> <span class="o">=></span> <span class="nv">$prefixes</span><span class="p">,</span> <span class="s1">'suffixes'</span> <span class="o">=></span> <span class="nv">$suffixes</span><span class="p">),</span> <span class="nv">$options</span><span class="p">);</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">JLayoutFile</span><span class="p">(</span><span class="nv">$layoutId</span><span class="p">,</span> <span class="k">null</span><span class="p">,</span> <span class="nv">$options</span><span class="p">);</span> <span class="p">}</span> </pre></div> <p>This gives a very flexible tool to developers.</p> <h1>Plugins improvements</h1> <h2>1. Layout support</h2> <p>Now in your plugin you can do something like:</p> <div class="highlight highlight-php"><pre><span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">getRenderer</span><span class="p">(</span><span class="s1">'default'</span><span class="p">)</span><span class="o">-></span><span class="na">render</span><span class="p">(</span> <span class="k">array</span><span class="p">(</span> <span class="s1">'context'</span> <span class="o">=></span> <span class="nv">$context</span><span class="p">,</span> <span class="s1">'row'</span> <span class="o">=></span> <span class="nv">$row</span><span class="p">,</span> <span class="s1">'params'</span> <span class="o">=></span> <span class="nv">$params</span><span class="p">,</span> <span class="s1">'page'</span> <span class="o">=></span> <span class="nv">$page</span> <span class="p">)</span> <span class="p">);</span> </pre></div> <p>It will search a <code>default.php</code> layout on:</p> <div class="highlight highlight-php"><pre><span class="k">Include</span> <span class="nx">Paths</span><span class="o">:</span> <span class="k">Array</span> <span class="p">(</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">templates</span><span class="o">/</span><span class="nx">protostar</span><span class="o">/</span><span class="nx">html</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=></span> <span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">jcms3x</span><span class="o">/</span><span class="nx">layouts</span><span class="o">/</span><span class="nx">plugins</span><span class="o">/</span><span class="nx">content</span><span class="o">/</span><span class="nx">vote</span> <span class="p">)</span> </pre></div> <p><strong>Note:</strong> All the plugins are still using the old hardcoded method. Only the plugin <code>content/vote</code> has been converted for testing purposes.</p> <h2>2. Layouts information on debug</h2> <p>Now the debug console shows all the information of the layouts loaded in the current page:</p> <p><a href="https://camo.githubusercontent.com/2856d4aebcf013eba68d5f4592eb07d2bba80f6a/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313131393237322f323331373633342f64356163363163342d613335312d313165332d383534622d6163616336386536353638612e706e67" target="_blank"><img src="https://camo.githubusercontent.com/2856d4aebcf013eba68d5f4592eb07d2bba80f6a/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313131393237322f323331373633342f64356163363163342d613335312d313165332d383534622d6163616336386536353638612e706e67" alt="layouts-article-form" data-canonical-src="https://f.cloud.github.com/assets/1119272/2317634/d5ac61c4-a351-11e3-854b-acac68e6568a.png" style="max-width:100%;"></a></p> <h1>Testing</h1> <p>Required tests include:</p> <ul class="task-list"> <li>Check that all list fields are shown and work correctly (including tags and all other extending fields)</li> <li>Check that user field works correctly</li> <li>Check that when you enable the option to show votes on articles it's dispalyed correctly</li> <li>Make performance tests with & without this patch to ensure that layouts doesn't overload system.</li> <li>Common layout override tests with prefixes, suffixes, include paths....</li> </ul> |
Labels |
Added:
?
|
Labels |
Added:
?
|
Labels |
Removed:
?
|
Labels |
Does anyone know what's happening with this PR?
Also, does this work with all form fields or just lists?
Sorry been meaning to reply to you on the mailing list! Basically we decided to expand the scope a bit and to implement it for the majority of form fields here: https://github.com/joomla-projects/cms-naked
However as you can probably see it lost popularity pretty quick. Me and @phproberto need to chat about what we're gonna do with it!
Oh okay, it's just that as it stands it's not possible to override the template (without a plugin) to accommodate any other CSS library that BS 2.3.
Would it be possible to just add layouts for the form fields? I can't see any b/c issues in doing this?
Can you point to any examples of where this has been done so that I can see the correct format / style for the overrides etc. I might be able to add them and put in a PR or two if I know what needs to be done.
Just use this PR as a base example with the rendering of the layouts. Or make a similar PR into the cms-naked branch and I have permissions there to merge that.
I completely agree by the way! I've hacked this into one of my sites to get integrations sorted in the frontend for the editing views.
Sorry @adster101 I should also jump into the issue. I was waiting for v3.5 but I think we have to start making that naked CMS.
I'll update the PR against the naked repo tonight and link it here so @wilsonge and me can use it as a starting point to also receive feedback.
Thanks!
Status | New | ⇒ | Pending |
Category | ⇒ | Layout |
What is 'naked' CMS? Is it just a place to add the layouts that will be merged into the staging branch at some point or something else?
@phproberto did you find time to update the repo?
Thanks.
Yeah so it's a place where we're gonna work on the next layer of making Joomla override-able. Firstly moving as much hardcoded stuff into JLayouts. But also thinking ahead a bit - adding in a getRenderer function (https://github.com/joomla-projects/cms-naked/blob/master/libraries/cms/plugin/plugin.php#L153 ) so that we can investigate not even being dependent on JLayouts.
The idea was that this would go into 3.5 (coming out ~now) but as you probably know 3.4 is being mega late so not quite sure where this is gonna fit in
Can you elaborate a bit on how the renderer would break the JLayout dependency? I mean what would the other rendering options be?
Is there any reason why this PR can't be merged with 3.4, when it's ready?
Can you elaborate a bit on how the renderer would break the JLayout dependency? I mean what would the other rendering options be?
Imho the longtime idea is that you could also use Twig or similar for rendering purposes. At least I understood it like this.
Is there any reason why this PR can't be merged with 3.4, when it's ready?
It could go into 3.4 in theory, but that would be something the release manager (currently for 3.4 that's David Hurley) has to decide. For 3.4, the main focus is a different one and since we're already delayed I wouldn't focus on this one. But if it gets ready in time, maybe it can be merged already.
On the other hand, the stuff in cms-naked is likely going to be a major focus for 3.5. So it would make sense to do this PR together with 3.5.
I am a bit play with new JLayoutFile
and it really cool thing
Have couple suggestions:
1 Posibility to get fullpath without rendering the layout file, something like:
public function getFullPath()
{
if (!is_null($this->fullPath))
{
return $this->fullPath;
}
// Search
return $this->getPath();
}
2 Throw Exception in render()
if no layout file found. Currently if no layout found user just get a blank page, that very confused. It not a problem when need to render 1-2 layouts, but when there 100 different layouts can be difficult to find out.
3 What about ability use the priority in addIncludePath()
?
Example, I want add own fallback path, so I do
$layout->addIncludePath('/root/path/my/fallback/path');
And got:
'includePaths' =>
array (
0 => string '/root/path/my/fallback/path'
1 => string '/root/path/templates/isis/html/layouts'
2 => string '/root/path/layouts'
)
That not really what I want, because I want that my fallback work only when no layout found in the template (or component) folder.
I think something like $layout->addIncludePath('/root/path/my/fallback/path', $priority);
would be cool, but I have no idea how this can be done
added:
I think it can be as b/k solution, for the priority support:
public function addIncludePathToPosition($path, $position = 0)
{
array_splice($this->includePaths, $position, 0, $path);
return $this;
}
Hi,
please ckeck out review of the code of class JLayoutFile
1) Suggest don't run any debug function if debug not requested in options. I undestand that it makes a lot of "if ($this->debug)" but perfomance is more important then pretty code
2) In getPath method call "find" twice
$this->fullPath = JPath::find($this->includePaths, $rawPath);
if ($this->fullPath = JPath::find($this->includePaths, $rawPath))
{
$this->addDebugMessage('<strong>Found layout:</strong> ' . $this->fullPath);
}
else
{
$this->addDebugMessage('<strong>Unable to find layout: </strong> ' . $this->layoutId);
}
3) Method JLayoutFile::getPath() checks that file exists so you don't need to check it again in JLayoutFile ::render() method
4) Sugest also make cache on JLayoutHelper::render level from $options passed to render method and keep JLayout instances as value. It will work faster then JLayout cache. As a consequence JLayout's cache can store paths for LayoutId only , without md5 from all options. Some times it also very usefull when developer knows that state of JLayout whould not be changed, so we don't calculate every "render" md5 and json.
What is the decision on this one? If it is ready to commit I would like to bring the fields user, media and content history (versions) to layouts and use bootstrap modal (for protostar and isis) and thus drop completely the loading of mootools on joomla core...
The decision is that it is being held back for Joomla 3.5 - but the JLayout conversion will be centre feature of that release
Sounds good, thanks George
one more note,
I will leave here before forget
about Prefixes support
suggested search with prefixes is: template with prefix
=> component with prefix
=> template without prefix
=> component without prefix
it make possible case when template override will not work
so I think would be better make search like: template with prefix
=> template without prefix
=> component with prefix
=> component without prefix
Status | Pending | ⇒ | Closed |
Closed_Date | 2014-03-04 09:50:52 | ⇒ | 2015-05-16 12:26:22 |
Closed_By | ⇒ | phproberto |
Labels |
Added:
?
|
Labels |
Added:
?
|
@phproberto why did you close this one? There’s another approach/solution/code for this?
I owe you so so so many beers :D :D