Support ⇒ Explain Please ⇒ How to template a block? ⇒ Community Forums ⇒ CPG Dragonfly™ CMS
Forum IndexExplain Please

How to template a block? Reply to topic


This is an example on how to get a block to use the template system.
I'm using a graphic-less version of the menu block.

BE WARNED: This block will work out of the box in v10, to make it work in v9 you need to replace SQL queries, and use $modheader instead of CSS::add, anyways the point of this post is "blocks and templates"

<?php /********************************************* CPG Dragonfly™ CMS ******************************************** Copyright © 2004 - 2005 by CPG-Nuke Dev Team www.dragonflycms.com Dragonfly is released under the terms and conditions of the GNU GPL version 2 or any later version $Source: /cvs/html/blocks/block-CPG_Main_Menu.php,v $ $Revision: 10.0 $ $Author: djmaze $ $Date: 2010/11/05 00:57:00 $ Encoding test: n-array summation ∑ latin ae w/ acute ǽ ********************************************************/ if (!defined('CPG_NUKE')) { exit; } global $prefix, $db, $userinfo; $modquery = $lnkquery = ''; if (!is_admin()) { $modquery = 'WHERE active=1 AND inmenu=1'; $lnkquery = 'WHERE active=1'; $view = array(); $view[] = 0; if (is_user()) { $view[] = 1; foreach($userinfo['_mem_of_groups'] AS $key => $value) { $view[] = $key+3; } } else { $view[] = 3; } $modquery .= ' AND view IN ('.implode(',', $view).')'; $lnkquery .= ' AND view IN ('.implode(',', $view).')'; } $result = $db->query('SELECT cid, name, link_type, link, pos FROM '.$prefix.'_modules_cat ORDER BY pos'); while ($cat = $result->fetch_assoc()) { $category[$cat['cid']] = $cat; $pos = $cat['pos']; } $result->free(); $category[0] = array('cid' => 0, 'name' => 'Ungrouped', 'link_type' => 0, 'link' => '', 'pos' => ++$pos); $result = $db->query('(SELECT mid AS lid, title, title as link, active, view, inmenu, cat_id, 0 as link_type, pos FROM '.$prefix.'_modules '.$modquery.') UNION (SELECT lid, title, link, active, view, 1 as inmenu, cat_id, link_type, pos FROM '.$prefix.'_modules_links '.$lnkquery.') ORDER BY pos'); while ($item = $result->fetch_assoc()) { $category[$item['cat_id']]['items'][] = $item; } $result->free(); CSS::add('themes/default/style/mmtxt.css'); $uri = substr(URL::uri(), 1); global $cpgtpl; foreach ($category as $cat) { if (empty($cat['items'])) continue; switch ($cat['link_type']) { case -1 > 0: if (empty($cat['link'])) { $cat['link'] = false; break; } case '0': $cat['link'] = URL::index($cat['link']); break; case 1: case 2: break; default: $cat['link'] = false; break; } $cpgtpl->assign_block_vars('blck_mmtxt_cat', array( 'S_TITLE' => defined($cat['name']) ? constant($cat['name']) : $cat['name'], 'S_LINK' => $cat['link'], 'S_VISITING' => $cat['link'] == $uri )); foreach ($cat['items'] as $item) { $type = ''; switch ($item['link_type']) { case 0: $item['link'] = URL::index($item['link']); break; case 1: break; case 2: $type = 'external'; break; default: $item['link'] = false; break; } switch (true) { case $type != '': break; case $item['active'] && $item['inmenu']: $type = 'ok'; break; case $item['active'] && !$item['inmenu']: $type = 'hidden'; break; case (bool) !$item['active']: $type = 'disabled'; break; default: continue; } $cpgtpl->assign_block_vars('blck_mmtxt_cat.item', array( 'S_TITLE' => defined($item['title']) ? constant($item['title']) : str_replace('_', ' ', $item['title']), 'S_LINK' => $item['link'], 'S_TYPE' => $type, 'S_VISITING' => $item['link'] == $uri )); } } $cpgtpl->set_handle('blck-mmtxt', 'blocks/mmtxt.html'); $content = $cpgtpl->to_string('blck-mmtxt');

<!-- BEGIN blck_mmtxt_cat --> <span class="blck-mmtxt_cat<!-- IF blck_mmtxt_cat.S_VISITING --> blck-mmtxt_visiting<!-- ENDIF -->"> <!-- IF blck_mmtxt_cat.S_LINK --> <a href="{blck_mmtxt_cat.S_LINK}">{blck_mmtxt_cat.S_TITLE}</a> <!-- ELSE --> {blck_mmtxt_cat.S_TITLE} <!-- ENDIF --> </span> <!-- BEGIN item --> <span class="blck-mmtxt_item <!-- IF blck_mmtxt_cat.item.S_TYPE == 'ok' -->blck-mmtxt_ok <!-- ELSEIF blck_mmtxt_cat.item.S_TYPE == 'hidden' -->blck-mmtxt_hidden <!-- ELSEIF blck_mmtxt_cat.item.S_TYPE == 'disabled' -->blck-mmtxt_disabled <!-- ENDIF --><!-- IF blck_mmtxt_cat.item.S_VISITING --> blck-mmtxt_active<!-- ENDIF -->"><a href="{blck_mmtxt_cat.item.S_LINK}">{blck_mmtxt_cat.item.S_TITLE}</a> </span> <!-- END item --> <!-- END blck_mmtxt_cat -->

The trick is:
$cpgtpl->set_handle('blck-mmtxt', 'blocks/mmtxt.html'); $content = $cpgtpl->to_string('blck-mmtxt');

This functionality was included more or less around v9.1, enjoy it.

.:: I met php the 03 December 2003 :: Unforgettable day! ::.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
CloudLinux / Apache 2.4 LSAPI / MySQLi 5.6 / PHP 5.6 / DCVS


"Center Up / Down" blocks are displayed after the head() function in header.php is called, and head() is what processes the global variable $modheader, so you can't use this technique in v9 if you want to add stylesheets to the header for "Center Up / Down" blocks (so it seems from my testing).

Gaming League / Cup - www.leaguecms.co.uk :: Other DragonFly modules - www.cmsdreams.co.uk

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):


Also, the to_string() method of the template class only appears in v10 as far as I can see, it's not in v9.3 or earlier. I have my own function to do the same as getting the output of a template into a string comes in very handy.

Gaming League / Cup - www.leaguecms.co.uk :: Other DragonFly modules - www.cmsdreams.co.uk

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):


To avoid too-late calls to $modheader you need something like this: if (file_exists('themes/'.$CPG_SESS['theme'].'/style/pro_news.css')) { $content = ' <style type="text/css"><!-- @import url(themes/'.$CPG_SESS['theme'].'/style/pro_news.css);/--></style>'; }

Although it does means living with an XHTML warning.

Pro_News CM™ - Content Management for Dragonfly CMS™

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
Linux / 1.3.39 - 2.4.9 / 5.5.42 - 5.6.16 / 5.4.37 - 5.5.11 / 9.4


I often thought that it would be great to refresh a block content using javascript and making an ajax call. This is in particular very interesting when dealing with shopping carts.

something like domain.tld/getblock?name=blockname

Something like that also require that all security and themings concerns are handled by such an interface.

If this is off topic simply move it or delete since it perhaps looses it's meaning when standalone.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
Linux/Apache/MySQL 5.1.49/PHP 5.3.6/ DF 9.3.2.0


@layingback, yeah you can do that, but Nano's opening post suggests you can add stuff to the header using "$modheader" in blocks, but you can't, at least not in v9, although I suspect it depends on the theme and the order of execution, for example most themes load left blocks in the "themeheader()" function and right blocks in "themefooter()" function, but not all do.

@movix, if you construct a module page to NOT call "header.php" you can put the output in a block (or anywhere else) via AJAX and still get all the security and template handling that DF provides.

The problem I have with calling standard module pages without the header is that DF still outputs various HTTP headers (in "cmsinit.inc") that means you can only send back HTML, you can't output, for example, JSON formatted data.

Gaming League / Cup - www.leaguecms.co.uk :: Other DragonFly modules - www.cmsdreams.co.uk

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):


Kendle wrote
@layingback, yeah you can do that, but Nano's opening post suggests you can add stuff to the header using "$modheader" in blocks, but you can't, at least not in v9, although I suspect it depends on the theme and the order of execution, for example most themes load left blocks in the "themeheader()" function and right blocks in "themefooter()" function, but not all do.


Agreed. Which is why I have to do it via the @import in Pro_News because I can't predict the block position or theme in use.

But where would you like to see the blocks loaded in, say, a revised reDesign3 theme? And what are the downsides of that choice?

Pro_News CM™ - Content Management for Dragonfly CMS™

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
Linux / 1.3.39 - 2.4.9 / 5.5.42 - 5.6.16 / 5.4.37 - 5.5.11 / 9.4


@Kendle:
I was sure it was included in v9 ... and yes too all others too.
In v10 things have changed a little, blocks are not generated by the theme anymore.
At the time of this writing are now handled by header.php: after theme.php is included but before themeheader() is called thus allowing blocks to add their css or js for caching and truly let themes to decide where to display them, eg top and bottom before the header, left and right on the left side ...
Moreover in admin modules you can now control -every- side independently.

@movix:
could achieve the same results using a dedicated ajax module, not the best option sure.

@layingback:
instead of
if (file_exists('themes/'.$CPG_SESS['theme'].'/style/pro_news.css')) { $content = ' <style type="text/css"> <!-- @import url(themes/'.$CPG_SESS['theme'].'/style/pro_news.css);/--> </style> '; }

You could
if (is_file('themes/'.$CPG_SESS['theme'].'/style/pro_news.css')) { $content = ' <style type="text/css"> '.file_get_contents("themes/{$CPG_SESS['theme']}/style/pro_news.css").' </style> '; }

.:: I met php the 03 December 2003 :: Unforgettable day! ::.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
CloudLinux / Apache 2.4 LSAPI / MySQLi 5.6 / PHP 5.6 / DCVS


Nano,

I couldn't get that to parse, although this did:<style type="text/css"> '.file_get_contents('themes/'.$CPG_SESS['theme'].'/style/pro_news.css').' </style> ';

But I fail to see the advantage. The XHMTL is still present (due to the <style ...> statement), and the CSS gets embedded in the HTML rather than pulled from the file (which is probably already cached by the browser).

You obviously haven't seen the size of my CSS files! Laughing

Pro_News CM™ - Content Management for Dragonfly CMS™

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
Linux / 1.3.39 - 2.4.9 / 5.5.42 - 5.6.16 / 5.4.37 - 5.5.11 / 9.4


If this is a block, I'm sure it wont use all of the css in the file ... a little bit of imagination?

.:: I met php the 03 December 2003 :: Unforgettable day! ::.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
CloudLinux / Apache 2.4 LSAPI / MySQLi 5.6 / PHP 5.6 / DCVS


layingback wrote
But where would you like to see the blocks loaded in, say, a revised reDesign3 theme? And what are the downsides of that choice?


I use reDesign3 on this site :-

www.urban-zone.org

... with a few tweaks.

In particular the side blocks are loaded in themefooter() AFTER the centre content. This was done because (on that site) they were posting content that was too wide for the centre content area and pushing the right blocks off and down to the bottom of the page.

I made it so the centre content displays first, in a DIV with a 200px margin on either side, and then in themefooter() load the left blocks into the left-hand 200px margin and right blocks into the right-hand 200px margin.

This ensures the right blocks always display where they're supposed to, but it also means if there is content in the middle that's too wide the extra effectively gets hidden under the right block(s).

3 column flexible width layouts using only CSS are a pain I've found, I tend to use fixed width themes more these days.

To be fair most "order of execution" issues can be resolved by not calling header.php until very late in the script, and designing the theme so that blocks are loaded after content.

The biggest bug bear I have at the moment is I want to return module pages without the header and blocks so as to insert them in a container via AJAX, which I can do, but I'd like to return the output as a JSON object (which is easy with PHP 5's json_encode() function), but that requires HTTP header "Content-type: application/json", which I can't set because "cmsinit.inc" has already set "Content-Type: text/html".

Gaming League / Cup - www.leaguecms.co.uk :: Other DragonFly modules - www.cmsdreams.co.uk

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):


NanoCaiordo wrote
@movix:
could achieve the same results using a dedicated ajax module, not the best option sure.



I guess i miss the point but anyway, if i take the answer to my question it leads me to make a distinct module - let's call it "block-renderer" - that takes a block and renders it as a simple output using any header i want.
The next point should be to write a theme that loads block contents throuh the "block-renderer" module using ajax.

I allready did things in some cases using this way. Not the best option ? why ? to much overhead ? Statistics get unreliable ?
Indeed the CSS question remains open when a block is diplayed out of his CSS context.

That said i wonder if such a functionality is worth to be included in the core that also reforges the way CSS or even $modheader is handled.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
Linux/Apache/MySQL 5.1.49/PHP 5.3.6/ DF 9.3.2.0


@Kendle
sending your new header -before- any output should replace it, requires a working output buffering.

@movix
"I" reckon creating a module to handle ajax within a block is not the proper way but it can be done, that's all.

What I prefer is that when talking about features/future, at least try to use HEAD cvs to see what is changed and start from there. If you do, only use "default" theme.

.:: I met php the 03 December 2003 :: Unforgettable day! ::.

Server specs (Server OS / Apache / MySQL / PHP / DragonflyCMS):
CloudLinux / Apache 2.4 LSAPI / MySQLi 5.6 / PHP 5.6 / DCVS

All times are UTC


Jump to: