View previous topic :: View next topic |
Author |
Message |
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Sat Nov 01, 2003 9:15 am Post subject: {cache} {/cache} |
|
|
Hi,
I have the following suggestion.
My templates are spilt into several logical sections.
Example
- Left mainmenu
- Top categories branch
- Middle col that contains a document text
- Authors of this document
- Right col. Links related to this document
- Right col. Documents title that are related to the main document of this page .
Links and related documents are generated through keywords, which connects the elements together.
The content is managed in an admin section and comes from a database.
The problem consists in how to cache such a page in an efficient way.
For example if I change a category name it isn’t very efficient to regenerate the cache for the whole page. I could split the logical sections in subtemplates, which have own caches. But this means that the templates were cuts in parts, which isn’t very handy for template designers.
The following function could be useful.
Code: |
Example:
{cache group=”aaa|bbb|ccc” id=”xxx”}
the code which generate the categories branch
{/cache}
|
In this way I can manage different caches in one template without dismantling the template in several sub templates. The whole template has one main cache and each logical section has its own cache.
atur |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Thu Nov 06, 2003 8:46 pm Post subject: |
|
|
atu,
as you may guess, i come from http://www.phpinsider.com/smarty-forum/viewtopic.php?p=5819
your problem above maybe doable, but i doubt that it will be easy and/or fast.
the idea i have on it needs a prefilter, a resource-plugin and an insert-function (or a non-cached-plugin-function as in 2.6.0). you see it's not really "easy".
the prefilter replaces all {cache}...{/cache}-blocks by
{insert name="cache_fetch" file="cache:{$smarty.template}#[number of the block]" cache_id=...}
the resource plugin takes files like "$name#$number". it reads the original $name and returns the $number'th {cache}...{/cache}-block as resource-contents.
the cache_fetch-insert-function calls $smarty->fetch() with the cache_id and returns the results.
does this sound reasonable? |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Thu Nov 06, 2003 8:58 pm Post subject: |
|
|
Yes this could be a possibility. I will check this. But as mentioned it may slow down the application. Lets see.........
Do you think to include such a function in a future release?
Thanks |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Sun Nov 09, 2003 5:35 pm Post subject: |
|
|
To be franck, messju's solution is to much for my little brain. Some where there is a limit on smarty's cache feature for some application architectures. But I have found an other solution.
The Smarty plugins in my application cache sql results. The performance gain is between 30%-50%. Each template has a cache group which is deleted from time to time. I think this is a good working solution. |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Mon Nov 10, 2003 8:46 am Post subject: |
|
|
atu wrote: | To be franck, messju's solution is to much for my little brain. |
no problem. it would be an ugly little hack anyway and doubtfully faster than no caching. maybe i will try my suggestion when there is time and mood, but not anytime soon.
another solution may be dropping smarty's caching in your application and cache the results of fetch() (some caching *around* smarty, instead of *inside* smarty). obviously this only works out if you don't rely on inserts and other dynamics in cached pages. |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Mon Nov 10, 2003 10:13 am Post subject: |
|
|
Quote: |
another solution may be dropping smarty's caching in your application and cache the results of fetch() (some caching *around* smarty, instead of *inside* smarty).
|
You mean a second kind of template engine which works on the fetch result?
Quote: |
obviously this only works out if you don't rely on inserts and other dynamics in cached pages.
|
So I cant make use of rdf plugins that are include in templates through inserts. |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Mon Nov 10, 2003 10:41 am Post subject: |
|
|
atu wrote: | You mean a second kind of template engine which works on the fetch result?
|
i don't mean a template engine but a content-cache. i think pear has a class that does this. you may get best results if you don't do it in php but even before with apache's mod_proxy or another load-balancing solution.
Quote: | So I cant make use of rdf plugins that are include in templates through inserts. |
nope. once the pages are cached, they are static then. |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Mon Nov 10, 2003 11:43 am Post subject: |
|
|
My solution is very similar to pear's cache_lite which is a pure php implementation. In combination with phpaccelerator it should be a good solution for high trafic sites even if smartys cache is disabled. May mmcache is a faster solution. |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Mon Nov 10, 2003 11:53 am Post subject: |
|
|
atu, here is my little stab at your plugin suggestion. Not as clean as messju's idea, I think, but perhaps a little bit simpler.
[php:1:c92d351348]<?php
/**
* block.sec.php
*
* Smarty cacheable template section block
*
* @author boots
* @version 0.1.4 2003-NOV-10
* @since 2003-NOV-10
* @see http://www.phpinsider.com/smarty-forum/viewtopic.php?p=5902#5902
* -----------------------------------------------------------------------------
* @param group required specify cache build group
* @param id required id within the cache build group
* @param ttl required time to live for template part/group
* @param template required expects $smarty.template
*/
function smarty_block_sec($params, $content, &$smarty, &$repeat)
{
// validation
extract ($params);
foreach (array('id', 'group', 'template', 'ttl') as $required) {
if (!isset($$required)) {
$smarty->trigger_error("sec block: $$required param missing. Aborted.");
return;
}
}
if (!isset($compile_id)) {
$compile_id = $smarty->compile_id;
}
$name = "$template.$id"; // sub-template target name
if (!isset($content)) {
// first iteration through block, so no content was processed
// try and read from the cache (if succeeds, do not re-enter block)
$_params = array(
'tpl_file' => $name
, 'cache_id' => $group
, 'compile_id' => $compile_id
);
require_once SMARTY_DIR.'core'.DIRECTORY_SEPARATOR.'core.read_cache_file.php';
if (smarty_core_read_cache_file($_params, $smarty)) {
$repeat = false;
echo $_params['results'];
}
} else {
// cache-miss:
// write out the sub-template
if (is_array($smarty->template_dir)) {
$params['filename'] = $smarty->template_dir[0];
} else {
$params['filename'] = $smarty->template_dir;
}
$params['filename'] .= DIRECTORY_SEPARATOR.$name;
$params['contents'] = $content;
require_once SMARTY_DIR.'core'.DIRECTORY_SEPARATOR.'core.write_file.php';
smarty_core_write_file($params, $smarty);
// cache the sub-template
$_ttl = $smarty->cache_lifetime;
$smarty->cache_lifetime = $ttl;
$_caching = $smarty->caching;
$smarty->caching = true;
$_id = $smarty->cache_id;
$content = $smarty->fetch($name, $group, $compile_id);
$smarty->caching = $_caching;
$smarty->cache_lifetime = $_ttl;
$smarty->cache_id = $_id;
return $content;
}
}
?>[/php:1:c92d351348]
it would be used much as you suggested:
Code: | {sec template=$smarty.template group=”aaa|bbb|ccc” id=”xxx” ttl=300}
the code which generate the categories branch
{/sec} |
It automatically adjusts your cache settings (turns cache on and sets the ttl=cache_lifetime) and creates subtemplate caches for the specified group then returns the settings back--so this should enable caching various portions of a page with varying ttls. I think that the outer template should have a low ttl for this to be effective (?). Cross-template effects should be possible if you wish to explore them. Seems to work with the built-in caching and andre's mmcache handler.
There is probably something glaringly wrong with what I did, but it is a little bit of a beginning you may be able to fashion into something more useful.
Last edited by boots on Tue Nov 11, 2003 3:13 pm; edited 3 times in total |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Mon Nov 10, 2003 12:33 pm Post subject: |
|
|
Many thanks boots!!!!. I will try this solution. I have to install the 2.6 version. I'm still working with the 2.5 version. |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Mon Nov 10, 2003 12:41 pm Post subject: |
|
|
boots, that's much simpler than what i had in mind |
|
Back to top |
|
atu Smarty Regular
Joined: 18 Apr 2003 Posts: 51 Location: Luxembourg
|
Posted: Mon Nov 10, 2003 1:15 pm Post subject: |
|
|
Code: |
{sec template=$smarty.template group=”aaa|bbb|ccc” id=”xxx” ttl=300}
the code which generate the categories branch
{/sec}
|
If this block function is included in a template which is also cached it seems that the ttl var is ignored. It should be similar to the insert function which is ignored by the cache of the parent template. |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Mon Nov 10, 2003 1:17 pm Post subject: |
|
|
boots: i may be wrong, but i think there is one little flaw in your plugin:
you first generate $content and then eventually use a cached version of it. i maybe wrong, but i'd change it to sth. like:
Code: |
if (isset($content)) {
/* we only get here when the block was not cached, see below */
// write the cache file
return $content;
} else {
if (is_cached()) {
// read the cache-file, echo the cached contents
$repeat = false; /* prevent the block from being executed */
}
/* the function get's called again with the content that is to cache */
}
|
|
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Mon Nov 10, 2003 6:09 pm Post subject: |
|
|
atu wrote: | If this block function is included in a template which is also cached it seems that the ttl var is ignored. It should be similar to the insert function which is ignored by the cache of the parent template. |
I'll consider this. Right now, the ttl is not actually ignored--but subtemplates can only be refreshed if the calling template has a lower overall ttl--since everything on the calling template gets "locked" in the template's cache image. ie. the sub-template can't be refreshed by the calling template unless the calling template is first refreshed.
The choices I see are either keeping the calling template with a low ttl (or perhaps uncached is best). Otherwise, as you suggest, all of the subtemplates will need some sort of insert like behaviour, which I'm not sure I fancy--but will investigate.
Last edited by boots on Mon Nov 10, 2003 6:33 pm; edited 3 times in total |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Mon Nov 10, 2003 6:12 pm Post subject: |
|
|
messju wrote: | you first generate $content and then eventually use a cached version of it. i maybe wrong, but i'd change it to sth. like:
Code: |
if (isset($content)) {
/* we only get here when the block was not cached, see below */
// write the cache file
return $content;
} else {
if (is_cached()) {
// read the cache-file, echo the cached contents
$repeat = false; /* prevent the block from being executed */
}
/* the function get's called again with the content that is to cache */
}
|
|
This is similar to the way I originally had it but while I was debugging, I decided to switch to the way I have it now. One thing I wasn't sure of is if it was ok to return content during the first call into block--obviously, the answer is yes I think I am somewhat ineffecient anyhow as when I write the subtemplate what I write is more akin to cache contents meaning that the compilation of the template file (and its subsequent compile file) are somewhat superfluous. Still, I was aiming for the simplest possible implementation, so all is not lost . Another thing is filters--I haven't considered those effects at all.
Thanks for the suggestion, messju! I will post again when I update the code.
Last edited by boots on Sat Nov 15, 2003 11:08 pm; edited 1 time in total |
|
Back to top |
|
|