Some questions regarding ZM

Help from core devs on creating themes for ZenMagick

Moderators: ckosloff, DerManoMann

Some questions regarding ZM

Postby yellow1912 » Tue Dec 01, 2009 1:14 pm

Since there is no general question forum, I guess this is the place to ask such questions?

Anyhow, a few questions:
1. I understand that a template can have many themes (or is it the other way around?)
2. I checked the default template/theme of ZM, and I want to suggest some small changes regarding the name of the objects/methods and such

I think the code used in the template/theme file should be easy to read/understand and remember.
Code: Select all
<?php if ($zm_theme->themeFileExists("theme.css")) { ?>
      <link rel="stylesheet" type="text/css" media="screen,projection" href="<?php $zm_theme->themeURL("theme.css") ?>" />
    <?php } ?>

better:

Code: Select all
$zm_theme->getCss("theme.css", "screen,projection");
// or just $zm_theme->getCss(); which will load all files. I will send you my newest cj loader class


This doesnt make any sense to me
Code: Select all
<?php if (null != ($bannerBox = ZMBanners::instance()->getBannerForSet('footer1'))) { ?>
            <div id="bannerFour"><?php $macro->showBanner($bannerBox); ?></div>
        <?php } ?>


better:
Code: Select all
<?php if (ZMBanners::exists('footer1')) { ?>
            <div id="bannerFour"><?php ZMBanners::show('footer1'); ?></div>
        <?php } ?>


This is php and ?
Code: Select all
<?php if (!ZMTemplateManager::instance()->isRightColEnabled()) { ?>
          body div#content {margin-right:20px;}
        <?php } ?>

The code is neither pure html or css thus very hard to read and understand

The mix use of class/static class and sometimes static class instance() also confused me a whole lot, perhaps we can have a better way to do this? What do you think Mano
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby ckosloff » Tue Dec 01, 2009 3:58 pm

There is a general question forum, it is called Zen Magick Cafe
http://forum.zenmagick.org/viewforum.php?f=18
According to your suggestions I have created a forum for devs to discuss creation of themes.
I moved your post there to keep the forum in order.
Thanks for your help.
If you are making $ out of ZenMagick, please consider a monthly contribution.
Don't strangle the hen that gives golden eggs.
To give back to the project is not generosity, just sound business practice.
User avatar
ckosloff
Soup Nazi
 
Posts: 176
Joined: Mon Oct 19, 2009 4:05 am
Location: South Florida

Re: Some questions regarding ZM

Postby DerManoMann » Wed Dec 02, 2009 12:02 am

Well, some of the default theme's shortcoming are most likely down to lack of proper CSS coding and therefore some hacking to make things work.
As far as the other (CSS/JS) including is concerned, if you look at a snapshot you'll see some different code that allows for things like the minify plugin I mentioned earlier.

As for the singleton style code - ideally there shouldn't be any need for templates to use that at all and for plugins/other backend code I guess it is ok as that's how things work. Also, adding heaps of static convenience methods doesn't really help to improve code readability, IMHO.

Things are still evolving, like, for example, the conversion of meta tags and crumbtrail to toolbox tools to avoid the singleton/static method issue.

It would be great if we could create feature requests for those things on sourceforge. We can still discuss them here and close the ones that are obsolete and keep the ones we want to implement. THat will be a lot easier to keep track of rather than me going through all the posts here trying to find things to implement.
It also means we can refer to specific requests when talking about what we are working on...

mano
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby yellow1912 » Wed Dec 02, 2009 2:09 am

Hi Mano,

Yes, lets discuss them here till we can find a good way to implement things, then I will put requests on sourceforge.

Regarding the theme arrangement and coding style, I think it is the best to learn from other frameworks and pick the best from them, what do you think?

---------------------------------------------------------------------------------

1. Zencart, for example, has one of the best ways to load css/js out there. The ability to load specific css/js per page without having to edit the template files is very very useful in many cases. Many other frameworks lack this ability. BTW, I have put all my cj loader into a class and package them here: http://public.rubikintegration.com/css_ ... loader.zip

2. Wordpress, for example, uses "hooks" in the template. You can have wp_header; wp_footer(); etc.... called inside your template files. The nice thing is that the plugins can add additional content or can process the content before WP prints them out there, and the users don't even need to edit the template files. Wouldn't it be nice that way?
For example, imagine that we can add cross-sell to the product info page without editing the template code at all, or with a minimal effort only.
For example, we can have something like this inside the product info template <?php print_block('product_plugins');?> and thus all plugins that hook into this block can be printed out here. I have an idea and also some code already written that could make this happen.

3. Magento, for example, use "layout" which is also nice. Users can have layout for 1,2,3,.. column display or whatever layout they want and then depending on the page they can specify the layout they want to use. Very convenient and easy to follow compare to the current zencart when the code to turn off columns etc placed inside 1 main tpl_main . I think ZM is currently providing something like that too.
I also see that css/js files are not placed in css/js folders and I don't think it's a good idea though.

Regarding ZM current template coding style I still think that some changes should be made to make things easier to read and remember. To be specific, for example: can we have showBanner method belongs to the ZMBanners class instead of macro? It just makes more sense to the users, and if you want you can actually simply call $macro inside your ZMBanners ::showBanner right?
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby DerManoMann » Wed Dec 02, 2009 9:44 am

yellow1912 wrote:This is php and ?
Code: Select all
<?php if (!ZMTemplateManager::instance()->isRightColEnabled()) { ?>
          body div#content {margin-right:20px;}
        <?php } ?>

The code is neither pure html or css thus very hard to read and understand

The mix use of class/static class and sometimes static class instance() also confused me a whole lot, perhaps we can have a better way to do this? What do you think Mano


Yes, I am sure we can. Again, the next version should bring some improvements. In the near future there will also be the following things to come:
* move more things into the toolbox - that should take care of the singleton stuff, at least for templates (and that is where it really matters, IMO)
* merge Theme and ThemeInfo class - there isn't much point to have both, in particular since some of the theme responsibility has moved into the new view classes

I also should probably apologize for the code above :oops: You are right, it's neither code nore CSS...
mano
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby DerManoMann » Wed Dec 02, 2009 10:16 am

yellow1912 wrote:1. Zencart, for example, has one of the best ways to load css/js out there. The ability to load specific css/js per page without having to edit the template files is very very useful in many cases. Many other frameworks lack this ability. BTW, I have put all my cj loader into a class and package them here: http://public.rubikintegration.com/css_ ... loader.zip

2. Wordpress, for example, uses "hooks" in the template. You can have wp_header; wp_footer(); etc.... called inside your template files. The nice thing is that the plugins can add additional content or can process the content before WP prints them out there, and the users don't even need to edit the template files. Wouldn't it be nice that way?
For example, imagine that we can add cross-sell to the product info page without editing the template code at all, or with a minimal effort only.
For example, we can have something like this inside the product info template <?php print_block('product_plugins');?> and thus all plugins that hook into this block can be printed out here. I have an idea and also some code already written that could make this happen.

3. Magento, for example, use "layout" which is also nice. Users can have layout for 1,2,3,.. column display or whatever layout they want and then depending on the page they can specify the layout they want to use. Very convenient and easy to follow compare to the current zencart when the code to turn off columns etc placed inside 1 main tpl_main . I think ZM is currently providing something like that too.
I also see that css/js files are not placed in css/js folders and I don't think it's a good idea though.

Regarding ZM current template coding style I still think that some changes should be made to make things easier to read and remember. To be specific, for example: can we have showBanner method belongs to the ZMBanners class instead of macro? It just makes more sense to the users, and if you want you can actually simply call $macro inside your ZMBanners ::showBanner right?


1. Well, ZenMagick can do that as well. If you have had a look at the header code in the default_layout.php you'll see that. I didn't bother wrapping that up much more to allow the user to refine things if needed.
I don't think we need something like <?php print_block('product_plugins');?>. Perhaps HTML comments to mark particular spots in the page, but not more.

2. Plugins can modify and rewrite all HTML content already, so it is mostly a matter of knowing where to do that. Plugins like pageStats, themeSwitcher, googleAnalytics, etc all use that. For example, the analytics plugin doesn't require any template work. The additional JS/HTML code gets injected before the closing <body> tag before the HTML is returned...

3. Yes, there is something similar - the theme info class allows to set different layouts for different pages. So you could perhaps drop the side columns during checkout to avoid distractions, etc. Also, since the name of the layout file gets configured, its possible to reuse them without having to make an extra copy for each different request (which is what zen cart does, I think).

Yes, the style can and perhaps should change. However, you got the dependencies wrong in your banner example. ZMBanners is the service class that implements the actual business logic of looking up stuff in the db, etc. $macros is a toolbox tool that acts as a wrapper around the servce (and takes away the singleton syntax, btw).
Current development aims to move everything into toolbox classes. Perhaps there should be more, perhaps they should be named differently.
The main reasons are:
a) The toolbox API docs are quite compact. That means that with starting at ZMToolbox it's easy to browse all the helper code that is provided for templates without having to browse all services, etc.
b) It's far simpler to customize toolbox classes by subclassing them
c) Toolbox tools contain all the code that might generate content and therefore I feel it is good to keep that together.

As for the theme/template distinction, in ZenMagick you can have multiple themes. One theme is active at a time (via the good old Zen Cart Template Selection page).
Each theme consists of multiple templates. These are typically views, other fragments (like the resultList stuff) or layout files.

CSS/JS are whereever I put them a long time ago. If you look at the CSS/JS include syntax, for example: <?php $utils->cssFile('theme.css') ?>, you'll notice that all filenames are relative to the content folder. So for new themes you are welcome to put files whereever you want.

mano
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby yellow1912 » Wed Dec 02, 2009 12:20 pm

1. I don't think we need something like <?php print_block('product_plugins');?>. Perhaps HTML comments to mark particular spots in the page, but not more.
--> We can certainly do that, though that will require parsing the content before printing it out, how does it affect performance? Did you happen to do any benchmark?
It might be easier to just use something like <?php print_block('product_plugins');?>, but then again if you think html comment is not so difficult then Im all for that because it's more elegant that way

Here is what I vision how easy this can make the "templating" task:
1. lets say we have a block called "product_plugins" placed somewhere in our product template file
Any plugin that needs to modify this block can "hook" into it. In the admin, we will be able to view the current plugins that hook into each block and can also change the order, for example I want the "reviews" plugins to display before the "testimonials" plugins, and that can be done easily in admin. These settings, however, should be theme/template specific

BTW, I thought a template should contain themes, not the other way around (ex: template "default" can contain theme "winter", "summer", "autumn",... Make more sense to me. It's not something critical though)

2. I'm also thinking of changing cj loader a bit so that files can be loaded at footer, will be perfect for many plugins. I cant wait to try it on ZM

3. Make sense. But still I think changes should be made to make it easier to use and remember, don't you think? Too many objects and classnames to remember can be very confusing.
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby DerManoMann » Wed Dec 02, 2009 10:08 pm

1. It's usually just a matter of doing a simple preg_replace() or str_replace(). I ended up using preg_replace looking like this:

$args['contents'] = preg_replace('/<\/body>/', $code . '</body>', $contents, 1);
return $args;

This is taken from the google analytics plugin. Besides being more elegant it doesn't limit plugins to specific blocks, but allows to twiddle any bit of HTML...

BTW: The layout manager that inserts the javascript also uses this technique.

Not sure about the admin side of things, though. Ok, order of execution is probably important, but you have that in the current plugin manager (similar to zen cart's modules). My view is that creating admin interfaces for all these aspects and permutations of options will be rather confusing and make the code overly complex just for the sake of having an UI rather than a few file based settings.

Another thing to keep in mind is this: If all these options are to be done on theme level it means it multiplies the number of combinations to manage. If, in the future, we were to add multi store/catalg code, it would add another factor.
I am really not a fan of admin interfaces to manage layout. This is the job of the theme/template!

I think the reason I chose theme rather than template is that I think it is really confusing to talk about templates as set of files that make up the UI and also template as a single file in a template!
To me, theme (or perhaps skin, if you like) seems to be the more common label for a set of files that control the UI of an app. Examples: Firefox (themes), VLC (skins), eclipse (themes)

2. I guess if you look at the minify plugin (should be in the latest snapshot) you have a good starting point for a cjLoader plugin :)

3. Agreed. $html and $net are pretty obvious to be (but then, I am a developer, in fact the developer!), but some of the others are probably not that great.
And my point was that it actually reduces the number of classes to remember. If you look at the apidocs for ZMToolbox, you'll find 7 public members. Those point to toolbox classes with documented methods available to templates. Seems easier to me than browsing through all the classes to figure out how things are done.
Also, the tools methods are designed for use in templates, so have slightly different parameters. Also they usually wrap up commonly used bits of code.

We could create a wiki page with suggestions for tool names and what method should be where...
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby yellow1912 » Thu Dec 03, 2009 1:08 am

I'm not saying we should try to manage the look via admin, I'm all against that. I can look at Zencart and see how much of a mess it can be to configure all the settings they currently have.

However, my point is that we can have a way to make it easy to let plugins hook into template, that would be a very good thing. Also, using "blocks" meaning that we can certainly cache by "blocks".

Controlling the order of these plugins mean that I can have the code of "reviews" appears before the code of "cross sell" without having to edit the code. However, if I want to control exactly how they look (floating them both the left for example) I have to use css
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby yellow1912 » Thu Dec 03, 2009 5:49 am

Just to clarify my point above:
1. If we use block like that, there is no need for the "sidebox layout control" anymore. The left column for example will be just a block called "left_column"
2. With that ability to use block as well as nested blocks it will make a huge difference in templating and writing plugins. We can now eliminate 90% the need to edit template file to install plugins and such

I'm really interested in this and willing to dedicate my time in developing this when I have a "green light" from you. So let me know your thoughts.
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby DerManoMann » Sun Dec 06, 2009 10:35 am

Hmm, does that mean the default sideboxes would need to be converted to plugins or similar in order to have callbacks? Where would you see sideboxes configured then? Wouldn't it be the easiest to leave it to the template author to just include whatever they want?
I think we need to distinguish between general purpose themes to be used as such and custom themes for a single client.

Apart from that, having had some time to think about this, my preliminary answer is this:

a) I like to think with the new savant based view code the $this->fetch() method is powerful enough to allow template authors to implement whatever they like for handling *any* block in their template.
I've been using velocity (Java templating engine) in a few projects and it never occurred to me that there should be some sort of plugin system to handle side-column contents. On the other hand, all custom code was done inhouse, so no need to fiddle with plugins or such.

b) I repeat: Using just a HTML comment will do the same and save having to write more code to register callbacks, etc. If we want to go for conventions, why not that. It would also allow plugins to support their own block markers without having to create new block functions each time (presumably that is actually not needed as there would just be a new string parameter being used?). Also, as long as no-one wants to modify a block no code is executed at all.

c) Either way,if it has to be a function (for whatever reason), I'd just like to get that added somewhere in the toolbox, or even the view classes.

Until then, I obviously can't stop you investigating this :) It might be a cool alternative way of handling template blocks.
My feeling is that to start with all can easily be done in a plugin as a proof of concept.

mano
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby yellow1912 » Sun Dec 06, 2009 12:22 pm

Hmm, does that mean the default sideboxes would need to be converted to plugins or similar in order to have callbacks? Where would you see sideboxes configured then? Wouldn't it be the easiest to leave it to the template author to just include whatever they want?

--> no need! We will use a hook system similar to auto_loaders of zencart but not quite the same
For example, we can have a function named "hook" (global function, you can put it into a class if you want '*'), well then when ever I want to register an output into a block, I just need to call hook('header','MyPlugin::output').
Obviously, these hooks need to be called before the template content is processed. (ideally in the modules/pages which should be loaded before view)

Of course the users can edit the template files like they always do in Zencart, but why do they have to do so if there is a much more elegant way to handle it?

Right now, if you want to display certain sideboxes on certain page, how much of a mess do you have to go through? Imagine using the system I proposed, you can even specify the exact content you want to display in each block and the order they appears per page (think of blocks as left column, right column, footer, header, ...). When a users install a new module, he goes to the admin, pick the page and the block on that page that he wants to display the plugin output. If he decides he wants to style it up a bit, obviously he needs to do so via the good old css stylesheets. However, for normal users, that will mean they ALMOST NEVER have to mess with coding again.

'*': IMHO there is no need to completely break away from global functions. Just like there is no need to completely break away from html table, when it is better to use table, use it
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby DerManoMann » Sun Dec 06, 2009 9:38 pm

I guess global functions are ok, but then, so are static methods on a class :)
One of the advantages of using classes, as practised in ZenMagick is that they can be replaced at runtime without having to modify anything.
Look at the mess all the SEO mods in zen cart make with renaming functions, etc. That's also the reason why I prefer the instance() syntax, as that allows to determine the actual implementation used on demand.

I think I need some more time to really appreciate the hook system. I imagine it could be for templates what events are for the backend...
I' rather not end with another system of nested arrays, but I guess that's just a matter of having a sensible UI. I suppose we could add a method to the plugins class where plugins expose the blocks they can generate and then it is just a matter of mix'n match...

Again (again), we could also avoid the hook method by mapping plugin blocks to something like <!-- hooks::sidebox::left --> but that is really a minor issue.
Sounds like the basic system is going to be quite simple and wouldn't really affect people if they don't want to use it. If you could create some prototype code I'd be happy to see if/how that could be integrated.

mano
DerManoMann
Founder
 
Posts: 305
Joined: Wed Oct 21, 2009 8:52 pm
Location: New Zealand

Re: Some questions regarding ZM

Postby yellow1912 » Mon Dec 07, 2009 1:53 am

Hi Mano,

I will be glad to. And yes you are right that if people dont use it, it doesnt matter, it will not break anything.

I wrote something for my Ajax Checkout class not too long ago to map content blocks, I will send you via email. It's an automate process so you dont have to declare which block is the parent and which one is the children etc...
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Re: Some questions regarding ZM

Postby yellow1912 » Wed Dec 09, 2009 6:06 pm

Here is some sample code for what I'm talking about, and note that while I may use php here you can use text replacement or whatever, the main thing is the idea

Code: Select all
<html>
<head>
<?php
if($template->startBlock('head')){
$template->endBlock();
}
?>
</head>
<body>
<div id="mainWrapper">
<div id="banner">
   <!-- some html code whatever here -->
</div>
<div id="contentWrapper">

<?php
if($template->startBlock('leftColumn')){
$template->endBlock();
}
?>


<?php
if($template->startBlock('content')){
   if($template->startBlock('subContent')){ ?>
      // nested block
      <!-- and we can also have some html code whatever here -->   
   <?php
      $template->endBlock();
   }
   
$template->endBlock();
}
?>


<?php
if($template->startBlock('rightColumn')){
$template->endBlock();
}
?>
</div>
<?php
if($template->startBlock('footer')){
$template->endBlock();
}
?>

</div>
</body>
</html>


Now say that I install my new ajax banner module, I want it to be displayed at the block 'content', all I have to do is to use the "block layout manager" and add the output from my block to this 'content' block, I can also set that I want it on the content block on a specific page only. If there are many other outputs hook into this block already, I can also edit the sort order and specify which one appears first.

What if I want it to be a sidebox, easy enough, just set it so that the output is appended to block 'leftColumn'. So here we don't even care about "sidebox" concept anymore, you can have sidebox, topbox, bottom box whatever. They are just "blocks" of content.

I will not have to change anything on the template file, and unless I want to style it up a bit I wont even have to edit my css file. The next time I update ZM or the plugin, I dont have to worry about anything since I did not edit anything.
yellow1912
Core Dev
 
Posts: 67
Joined: Sat Nov 28, 2009 2:24 pm

Next

Return to Themes

Who is online

Users browsing this forum: No registered users and 1 guest

cron