difference between getChildHtml() and getChildChildHtml() in Magento - templates

I want to know the differences between this two functions. I understand the behavior of getChildHtml(). It returns the html of the block or all the blocks if you donĀ“t pass any parameters.
And I can see
getChildHtml($name, $useCache, $sorted)
getChildChildHtml($name, $childName,$useCache, $sorted)
at first sight I a $useCache param that I suposed is to use cache.

Let's say you're in the root block's phtml template file, and you have a simplified block structure that looks like this
root
left
promo_top
navigation
promo_bottom
center
right
From the root block's template file, to print the left block you'd use getChildHtml.
echo $this->getChildHtml('left');
However, if for some reason you wanted to print the promo_top block in the root template, you'd have to do something like this
$left = $this->getChildBlock('left')
echo $left->getChildHtml('promo_top')
The getChildChildHtml method allows you to do this sort of thing in one simple method call. Again, from the root template
echo $this->getChildChildHtml('left','promo_top');
So, the semantics are
Get My Child Block with the name X
Then, get it's child block with the Y
Render the HTML
If you look at the source code you can see that, ultimately, this method just wraps a call to getChildHtml
#File: app/code/core/Mage/Core/Block/Abstract.php
public function getChildChildHtml($name, $childName = '', $useCache = true, $sorted = false)
{
if (empty($name)) {
return '';
}
$child = $this->getChild($name);
if (!$child) {
return '';
}
return $child->getChildHtml($childName, $useCache, $sorted);
}

Related

tt_address: add categorys of address to the template

Is it somehow possible to add the sub-group of a cetrain group the address is assigned to the html output?
In the template I have ###MAINGROUP### and ###GROUPLIST###. I can't use maingroup, cause it's not the case that the group I need is always the maingroup. And with the grouplist I can't say which group is the sub-group of the one group.
Anyone have an idea how I could do it?
And in addition to that I also need the value of a self created field in the tt_address table.
Edit:
I try it like #lorenz say. What I have so far:
ext_localconf.php:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][]
='EXT:txnextaddresssort/class.tx_next_address_sort_addmarkers.php:tx_next_address_sort_addmarkers';
class.tx_next_address_sort_addmarkers.php:
<?php
class tx_next_address_sort_addmarkers {
function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf,
&$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###SORTBEREICH###'] =
$lcObj->stdWrap($address['tx_nextaddresssort_sort_bereich'],
$lConf['tx_nextaddresssort_sort_bereich.']);
}
}
Extentionkey: next_address_sort
All I get is a blank screen, but no errors in apache log
No, there is no possibility to do that.
Yet you can write a custom extension that integrates the extraItemMarkerProcessorhook in tt_address. In ext_localconf.php, add:
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][] ='EXT:myextension/class.tx_myextension_filename.php:tx_myextension_classname';
Then add a file class.tx_myextension_filename.php to your extension.:
class tx_myextension_classname {
public function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf, &$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###MYFIELD###'] = $lcObj->stdWrap($address['myfieldlikeindatabase'], $lConf['myfieldlikeindatabase.']);
return $markerArray;
}
}
This would be an example for getting a field that is in the tt_address table and adding it to the markers so they can be used in a template. It is also stdWrap enabled.
Now, instead of getting a field, you should replace $address['myfieldlikeindatabase'] with a variable that contains the information you need. To receive the data, you can use the TYPO3 database API functions ($GLOBALS['TYPO3_DB']).

Opencart: How to render a template only on a specific page?

In my catalog/controller/mycontroller.php, I have a script like this:
$this->data['settings'] = $this->config->get('my_module'); // retrieves data from "setting" table
foreach ($this->data['settings'] as $data) {
if ($data['pageurl'] == 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']) {
$this->render();
}
}
In Extensions > Modules, I have my extension installed where I can set different page URLs to different Layouts and Positions like this:
Page URL Layout Position
================================================
http://...?product_id=10 Product Content Top
http://...?product_id=20 Product Content Top
http://... Home Content Top
My issue is - I'd like to render a template only ONCE on a specific page that meets the condition in the above script. What's currently happening is $this->render() is showing the template MULTIPLE times based on the Position and Layout in Extensions > Modules. For instance, when I visit http://...?product_id=10 page, it displays the template twice while it's only supposed to display it once because it only meets the condition for product_id=10 in the controller. How can I do this?
First of all, do this:
var_dump('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
I guess You may be missing also the $_SERVER['QUERY_STRING'] part...
to see, what URL are You building to compare to URLs You are setting in the backend...
Next, please, do not call $this->render() in a loop no matter why the condition succeed more times, instead of this do something like this:
$this->data['settings'] = $this->config->get('my_module'); // retrieves data from "setting" table
$render = false;
foreach ($this->data['settings'] as $data) {
if ($data['pageurl'] == HTTP_SERVER . $_SERVER['REQUEST_URI']) { // use defined constant HTTP_SERVER
$render = true;
}
}
if($render) {
$this->render();
}

How to write a boundHelper to iterate a map in Ember.js

I have a model which contains an Ember.Map, and I want to render the content of that map in a template.
I've tried using the custom bound helper below, but the template will not re-render as values are added/removed from the map.
Essentially I just want to replicate the behaviour of {{#each}} for a map.
Ember.Handlebars.registerBoundHelper('eachInMap', function(map, block) {
out = "";
map.forEach(function(k,v) {
out += block.fn(v)
});
return new Handlebars.SafeString(out);
}, /* what dependencies to put here? */);
Invoked by a template
{{#eachInMap myMap}} foo bar {{/eachInMap}}
Check out https://github.com/emberjs/ember.js/pull/2659.
Basically, boundHelpers don't currently support blocks sorry.
The current workaround is to create a non-bound helper and wrap it in a {{#bind}} block.

PlayFramework 2.0 - Not able to call functions from other templates

I want to place some helper functions in another file, since they will be overly reused. I took the Computer-Databse sample's listing file:
https://github.com/playframework/Play20/blob/master/samples/scala/computer-database/app/views/list.scala.html
I created a new file, called "listing.scala.html" under the app/views package, and moved the #link function from the original file to it. This new file looks like this:
#(currentSortBy: String, currentOrder: String, currentFilter: String)
#****************************************
* Helper generating navigation links *
****************************************#
#link(newPage:Int, newSortBy:String) = #{
var sortBy = currentSortBy
var order = currentOrder
if(newSortBy != null) {
sortBy = newSortBy
if(currentSortBy == newSortBy) {
if(currentOrder == "asc") {
order = "desc"
} else {
order = "asc"
}
} else {
order = "asc"
}
}
// Generate the link
routes.Application.listPerfil(newPage, sortBy, order, currentFilter)
}
So, on my original file, I replaced the #link call, with this one:
#title
And the problem is, when I try to compile I get this error:
value link is not a member of play.api.templates.Html
But according to the documentation (http://www.playframework.org/documentation/2.0.4/ScalaTemplateUseCases) it seems to be ok.
Any guess?
Play's templates aren't the best place for placing advanced conditions, most probably you'll get better flexibility by processing it in some controller (or other method) which will return you only required link
ie.:
#title
In your case proposed link(...) function of Application controller can also return a reverse-route.
Keep in mind that including other templates is best option for repeating blocks of HTML but sometimes it's hard to get specified string (mainly because of not trimmed spaces). As you can see there is also problem with calling nested functions. Most probably you can generate whole A tag in the listing.scala.html however using it isn't comfortable enough (IMHO).

Ignore or replace Handlebars blocks that don't compile

In a handlebars template in Ember.js, I have blocks like the following:
{{content.some_attribute}}
{{content.some_other_attr}}
{{content.more_attr}}
Some of these attributes don't exist and I'm implementing them slowly.
Is there a way to get these templates to compile and either ignore the blocks that don't evaluate or better yet, replace them with a html element so they're easier to spot in the browser?
(the template is pretty large and it's being converted from ERB slowly,
Is there a way to get these templates to compile and either ignore the blocks that don't evaluate
Properties that don't exist are undefined, and don't get rendered at all. In other words {{thisDoesNotExist}} will simply be invisible -- it will compile just fine.
or better yet, replace them with a html element so they're easier to spot in the browser
As Cory said, you could use a helper for this that checks for undefined, using Ember.Handlebars.registerBoundHelper.
This seems like a perfect case for a handlebars helper. The helper could validate the value and return the value or the html that you desire.
The following code should be used very carefully, since it has not been tested within an application.
A possible solution to replace the possible undefined value in a template is to overwrite Ember.getPath, which is used to lookup the value of a path in a template, see http://jsfiddle.net/pangratz666/hKK8p/:
var getPath = Ember.getPath;
Ember.getPath = function(obj, path) {
var value = getPath(obj, path);
return (Ember.none(value) ? 'OMG %# is not defined!!'.fmt(path) : value);
};
If this code would be used temporarily in an application, I would also restrict the check for undefined values to a specific obj. So something along those lines:
App.objectWhichHasUndefinedProps = Ember.Object.create({
...
});
Ember.View.create({
templateName: 'templateWithAttributes',
objBinding: 'App.objectWhichHasUndefinedProps'
}).append();
var getPath = Ember.getPath;
Ember.getPath = function(obj, path) {
var value = getPath(obj, path);
if (obj === App.objectWhichHasUndefinedProps) {
return (Ember.none(value) ? 'OMG %# is not defined!!'.fmt(path) : value);
}
return value;
};