klox7 VIP
Total posts: 914
01 Jul 2014 17:18

I hope I will ask this as celar as possible...

I have several content types with different fields and different number of fields. For all sections and content types I would like to use only one template. I know Cobalt already has core templates and you can use one for several types (using php foreach ($item->fields_by_id AS $field):) but I don't think that's what I want.

Examples:
* Type1 -> fields a, b, c, d, e
* Type2 -> fields 1, 2, 3, 4, 5
* Type3 -> fields a1, b2, c3, d4, e5

Let's say we have 3 divs - top, main, bottom.

I would like to display fields like this (fields have to corespond to content type):
* div.top -> fields d, e
* div.main -> fields a, b, 4, e5
* div.top -> fields 3, b2

So if I'm in record list of Content Type1 I would like to display in div.main only fields from this Type (a, b). Even though there are also other fields form other content types added template. If I'm in record list of Content Type2 then in div.main there is field 4.

Is there any good practice how to achieve this?

Last Modified: 20 Apr 2015


Sergey
Total posts: 13,748
02 Jul 2014 01:00

So you want to create universal template. That is good.

First you have to understand what is field key. If for example div.top -> fields d, e but d and e is the same field name price and type digits you can display it through key

<?php $key = $this->fields_keys_by_id[12];?>
<?php if(isset($item->fields_by_key[$key])): ?>
    <span class="top">
        <?php echo $item->fields_by_key[$key]->result; ?>
    </span>
<?php endif; ?> 

But if those fields are different, you have to create parameter with fields list in template parameters.

<field name="field_top" type="meresourcesfields" label="What do we show in TOP div?" />

You can select as many filters theer as you want from different types. And then.

$fields = $params->get('tmpl_params.field_top');
foreach($fields AS $field) {
    if(isset($item->fields_by_id[$field]))
    {
         echo $item->fields_by_id[$field]->result;
    }
}

This all is described here.

http://docs.mintjoomla.com/en/cobalt/custom-templates-article/


klox7 VIP
Total posts: 914
02 Jul 2014 09:44

<?php $key = $this->fields_keys_by_id[12];?>

So when using this it will check field id 12 and match it to fields with same Label and field type?

But I must definitely do it with parameters. Seems like there is more you can do with it.


Sergey
Total posts: 13,748
02 Jul 2014 10:37

klox7 So when using this it will check field id 12 and match it to fields with same Label and field type?

Yes. ID is unique per fiel and key is not. Different types may have the same key fields.

klox7 But I must definitely do it with parameters. Seems like there is more you can do with it.

This really depends on your task. You also hav to remember that for every section parameters are different and you select only fields of that section with may even lower template to the by ID fields display.


klox7 VIP
Total posts: 914
02 Jul 2014 17:49

Sergey You also hav to remember that for every section parameters are different and you select only fields of that section with may even lower template to the by ID fields display.

Yes but with template parameters admin just clicks. It doesn't have to have in mind that field must have the same label. And there is posibility to quickly select another field.


klox7 VIP
Total posts: 914
02 Jul 2014 19:55

Foreach gives warning

Warning: Invalid argument supplied for foreach()

This works

<?php if(isset($item->fields_by_key[$params->get('tmpl_params.field_top')])):?>
    <?php echo $item->fields_by_key[$params->get('tmpl_params.field_top')]->result; ?>
<?php endif; ?>

Sergey
Total posts: 13,748
02 Jul 2014 23:38

Yes, your code works with single field selector. And you could see that you can select only one field. So there is no sence for foreach cycle.

<field name="field_top" type="meresourcesfields" label="What do we show in TOP div?" />

but if you want to select multiple fields

<field name="field_top" multi="true" type="meresourcesfields" label="What do we show in TOP div?" />

Then this parameter will return array.


klox7 VIP
Total posts: 914
03 Jul 2014 19:29

I stumbled on another problem when creating universal template.

At the moment I'm creating records list template. I added filed parameters for all types. So one parameter is for one type and other parameter for other type.

But when I look at page of type1 I get Notice: undefined index because I have added fields from type2 in template. Can this be solved?


Sergey
Total posts: 13,748
04 Jul 2014 00:35
  1. Why do you have 2 differnt parameters? Is there a case when you select something in both parameters at the same time? I am sure no. Then it have to be one parameter. But simply in parameters of this template in one section we select one tipe and in other section another type.
  2. To get read of the notice, you have to check if array is empty. How me the line whach produce notice.

klox7 VIP
Total posts: 914
04 Jul 2014 07:14

This is code I use for fields

<?php
$var = $item->fields_by_key[$params->get('tmpl_params.field_myfield')];
if(isset($var)):?>
    <?php if($var->params->get('core.show_lable') > 1):?>
        <dt class="<?php echo 'lbl-'.$var->id;?> <?php echo $var->params->get('core.lable_class');?> <?php echo ($var->params->get('core.label_break') > 1 ? ' line-brk' : NULL) ?>">
            <?php echo $var->label; ?>
            <?php if($var->params->get('core.icon')):?>
                <?php echo HTMLFormatHelper::icon($var->params->get('core.icon'));  ?>
            <?php endif;?>
        </dt>
    <?php endif; ?>
    <dd class="<?php echo 'rslt-'.$var->id; ?> <?php echo $var->params->get('core.field_class');?>">
    <?php echo $var->result; ?>
    </dd>
<?php endif; ?>

Sergey Why do you have 2 differnt parameters?

Well, fields from one type and another are not always positioned in same place. Ant there are some fields the are in common for both types but some are different.

Let's say Type1 has Field1 and Type2 has Field2. Field1 is displayed somewhere on top and Field2 somwhere on bottom. So I can't use 1 parameter for both fields, right? So if I'm configuring template for Type1 I will choose Field1 in parameters and leave Field2 empty. For Type2 is other way around.


Sergey
Total posts: 13,748
06 Jul 2014 12:33
  1. I think by default $params->get('tmpl_params.field_myfield') will have ID not a key. What is your XML for this parameter?

    make echo $params->get('tmpl_params.field_myfield') and make sure it is key not id.

  2. in the sode better use empty(). It prevent for notice if field is not there.
<?php if(!empty($item->fields_by_key[$params->get('tmpl_params.field_myfield')])): ?>
    <?php $var = $item->fields_by_key[$params->get('tmpl_params.field_myfield')]);?>
    <?php if($var->params->get('core.show_lable') > 1):?>
        <dt class="<?php echo 'lbl-'.$var->id;?> <?php echo $var->params->get('core.lable_class');?> <?php echo ($var->params->get('core.label_break') > 1 ? ' line-brk' : NULL) ?>">
            <?php echo $var->label; ?>
            <?php if($var->params->get('core.icon')):?>
                <?php echo HTMLFormatHelper::icon($var->params->get('core.icon'));  ?>
            <?php endif;?>
        </dt>
    <?php endif; ?>
    <dd class="<?php echo 'rslt-'.$var->id; ?> <?php echo $var->params->get('core.field_class');?>">
        <?php echo $var->result; ?>
    </dd>
<?php endif; ?>

klox7 VIP
Total posts: 914
07 Jul 2014 08:09

Sergey What is your XML for this parameter?

This is the whole custom XML at the moment. Btw the template is for records list.

<fieldset name="common_fields" label="Common fields">
    <field name="field_image" type="meresourcesfields" label="Select Image field" />
    <field name="field_description" type="meresourcesfields" label="Select Description field" />
    <field name="field_spa_type" type="meresourcesfields" label="Select Spa type field" />
    <field name="field_thermal_water" type="meresourcesfields" label="Select Thermal water field" />
    <field name="field_map" type="meresourcesfields" label="Select Map field" />
</fieldset>
<fieldset name="resort_fields" label="Resort fields">
    <field name="field_accomodation" type="meresourcesfields" label="Select Accomodation field" />
</fieldset>
<fieldset name="accomodation_fields" label="Accomodation fields">
    <field name="field_accomodation_resort" type="meresourcesfields" label="Select parent Resort of this Accomodation" />
    <field name="field_accomodation_category" type="meresourcesfields" label="Select Accomodation category field" />
</fieldset>
  • common_fields are fields used in all sections
  • resort_fields are fields used only in one section (Resort section)
  • accomodation_fields are fields used only in one section (Accomodation section)

Right now I'm trying to configure template for Accomodation section.

custom_fields shows ok when selected, if not I get something like Notice: Undefined index: k58d0e463a6f3400ff539f29a3fc653d1. I added !empty but notice is still there. If I use isset i get same notice but without key number.

Since this is configuration for Accomodation section I don't want to select fields meant for Resort section. So I'm leaving resorts_fields empty and I get Notice.

But this Notice for empty field parameter is not a problem because I can turn error reporting off and notice is gone.

The main problem I have is for accomodation_fields. field_accomodation_resort (accomodation type) is a child field of resort type (resort type has parent field Accomodation).

I'm displaying results for this field like this:

<?php //resort
$resort = $item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')];
if(!empty($resort)):?>
    <div class="resort <?php echo 'rslt-'.$resort->id; ?> <?php echo $resort->params->get('core.field_class');?>">
     <?php echo $resort->result; ?>
     </div>
<?php endif; ?>

You don't select this "Resort" field when submiting Accomodation becuse it should get parent automatically. But since I get Notice also for this field something must be wrong. Otherwise it should display title of parent.


Sergey
Total posts: 13,748
08 Jul 2014 00:03

Look my code more careful again. It is important that you make $resort = $item->fields_by_key[$pa.... only after IF. So in your code that will be

if(!empty($item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')])):
$resort = $item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')];

or you have to use @ to suppres error

<?php //resort
$resort = @$item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')];
if(!empty($resort)):?>

klox7 VIP
Total posts: 914
08 Jul 2014 08:36

Sergey only after IF

Sorry, missed it totally, but it makes sense and it's working. But I still can't get title of parent record.


Sergey
Total posts: 13,748
08 Jul 2014 09:03

klox7 But I still can't get title of parent record.

Where? You mean your article is a comment to some other article?


klox7 VIP
Total posts: 914
08 Jul 2014 09:13

My article (Accomodation) is a child to some other article (Resort).

So when in Accomodation article I get Resort Title with:

<?php //resort title
if(isset($item->fields_by_id[parent_field_in_resort])): ?>
    <?php echo $item->fields_by_id[child_field_in_accomodation]->result; ?>
<?php endif; ?>    

In record list template I have this parameters:

<fieldset name="accomodation_fields" label="Accomodation fields">
    <field name="field_accomodation_resort" type="meresourcesfields" label="Select parent Resort of this Accomodation" />
    <field name="field_accomodation_category" type="meresourcesfields" label="Select Accomodation category field" />
</fieldset>

For field_accomodation_resort I selected child field in Accomodation type.

My code in template is this:

<?php //resort
if(!empty($item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')])):
$resort = $item->fields_by_key[$params->get('tmpl_params.field_accomodation_resort')]; ?>
    <div class="resort <?php echo 'rslt-'.$resort->id; ?> <?php echo $resort->params->get('core.field_class');?>">
     <?php echo $params->get('tmpl_params.field_accomodation_resort') ?>
     </div>
<?php endif; ?>

I'm also using custom template just for displaying title:

<?php foreach ($this->items AS $item):?>
    <?php
    $ll = array();
    ?>
    Resort:
    <a <?php echo $item->nofollow ? 'rel="nofollow"' : '';?> href="/<?php echo JRoute::_($item->url);?>">
        <?php echo $item->title?>
    </a>
<?php endforeach;?>

But somehow Title of parent (Resort) isn't displayed.


Sergey
Total posts: 13,748
08 Jul 2014 10:04

In first example you check for parent_field_in_resort but show child_field_in_accomodation. Not right.

In 3d example instead of <?php echo $params->get('tmpl_params.field_accomodation_resort') ?> you have to use <?php echo $resort->result; ?>

in last example instead of href="/ use href=". Other words delete /.


klox7 VIP
Total posts: 914
08 Jul 2014 18:16

Sergey In first example you check for parent_field_in_resort but show child_field_in_accomodation. Not right.

Yeah right. Misinformation. I'm checking same field, that's child_field_in_accomodation.

Sergey In 3d example instead of &lt;?php echo $params-&gt;get('tmpl_params.field_accomodation_resort') ?&gt; you have to use &lt;?php echo $resort-&gt;result; ?&gt;

Thanks, I missed this. I am in need of vacation.


klox7 VIP
Total posts: 914
08 Jul 2014 18:28

@Sergey if you will do universal template what would be your approach? I'm thinking of creating one for depot with field list in template parameters. Mainly because if you don't do custom template you can't show fields in order as you want (admin order excluded). With this kind of template users will just select fields for position.

But I don't know how many fields will somebody use. So my question is if it is OK to crate let's say 50 field parameters and users just select the ones they want. Or will there be to many db queries?


Sergey
Total posts: 13,748
09 Jul 2014 03:03

klox7 With this kind of template users will just select fields for position.

This is the way I would go. I would markup template for positions like general Joomla template. I would create small miniature that show other users what positions are where. Then I would create parameter set for every position. You can select one or few fields inside position. You also may select style. For example DT/DD style, table style, ... This is how щнг want your fields to be displaied. Also show labels or not, if show labels then above or on the side, position class, ...

I would create a universal function inside template that can accept all those parameters and display fields acordingly.

function showPosition($fields, $style, $labels, ...)
{
   ....
}

Then in every position I would simply

if($params->get('tmpl_params.field_position1'))
{
    showPosition($params->get('tmpl_params.field_position1'), $params->get('tmpl_params.position1_style'), $params->get('tmpl_params.position1_show_label'), ...);
}

Then you can invent more parameters for every position paraeters grou and it will immediaty extend whole template.

This is the way I would go.


klox7 VIP
Total posts: 914
12 Aug 2014 09:49

I just noticed if I change field label and field is selected through template parameters then it's not selected anymore in parameters. Can I somehow select field in params based on id. I tried with key="id" but no success.

Powered by Cobalt