Re: [PHPTAL] Variable interpolation inside structure'd expression
In the original PhpTal it was not possible to automatically parse arbitrary strings, I don't know if this feature has been introduced in later releases. The common approach is to execute the string as a template, introducing the result in the actual template context. If this is a pattern that repeats itself quite a bit, you can wrap that functionality inside a custom modifier so that you can do stuff like this: div tal:content=structure tpl:product/descr.../div regards, /imv ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] while loop in PHPTAL
Yeah, I thought about using LimitIterator [1] to avoid the creation of temporary arrays but I wasn't sure about the performance of it (does it always seek?) or if it works with Traversables. A custom LimitIterator, without seeking, might of course work, or perhaps it's enough to just modify the code and use a SplFixedArray object to ensure constant memory usage, without relying on PHP's garbage collector to do the job. [1] http://php.net/limititerator /imv On 1/4/10 3:19 PM, Kornel Lesiński wrote: On 31-12-2009 at 15:23:20 Iván Montes drsl...@pollinimini.net wrote: I've put together a very simple chunk iterator [1] which works with arrays, traversables and iterators. There is also an example tales modifier. Perhaps it could even be added to the standard PHPTAL code base? [1] http://gist.github.com/266759 Thank you. That's a good start, but doesn't avoid creation of arrays yet. What I actually had in mind was pair of iterators (one for rows like you've created, another for each row) that doesn't create PHP array at any point, just passes calls to the innermost iterator. That would ensure constant memory usage (rather than 1/number_of_columns) on arbitrarily large iterations, which I think is the major reason to use iterators instead of (presumably faster) array_chunk(iterator_to_array()). ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] while loop in PHPTAL
Hi, I've put together a very simple chunk iterator [1] which works with arrays, traversables and iterators. There is also an example tales modifier. Perhaps it could even be added to the standard PHPTAL code base? [1] http://gist.github.com/266759 regards, /imv On 12/31/09 11:02 AM, Kornel Lesiński wrote: On 31-12-2009 at 04:44:34 romtek rom...@gmail.com wrote: Thank you very much for this sample! It's much more elegant, easier to understand and maintain than what I've come up with. Things like this had better be published in a special section of documentation. And I hope that array_chunk() doesn't copy data needlessly. This method does introduce more overhead. Kornel, what would you do if data were a collection but not an array (besides using something like what was suggested by Rasmus Schultz at http://php.net/manual/en/function.array-chunk.php)? If it's small enough to fit in memory, then probably conversion to array with iterator_to_array() will be fastest. Otherwise you could write something like IteratorIterator http://www.php.net/IteratorIterator that ignores reset() and pretends it ends every n elements. ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] Support for PHP 5.3 closures
I fail to see why checking for closures makes variable access much slower. As far as I remember, interpolated variable paths are compiled to use the $ctx-path() method, and it already does quite a few type checking logic already. Checking for a closure basically would mean adding instanceof conditions, being instanceof an operator and as such extremely fast, I don't see why it should hurt overall performance. best regards, /imv On 12/23/09 6:42 PM, Kornel Lesiński wrote: In PHP 5.3 you can create function on the fly: $phptal-variable = function() { return Hello World; } This looks like a great solution for lazy loading of data - instead of loading data up front, you just wrap it in a function that will be called in template when needed. I've hoped to create no-syntax syntax for it, i.e. the code above would automatically execute function: ${variable} == Hello World Although this is doable, it would make some optimisations impossible, and in turn make PHPTAL's variable access much slower (basically every time any variable is accessed, I'd have to check if it's a closure). So I'm thinking about alternative syntax for it that would make execution of closures explicit. ${variable/invoke} or ${variable/()}? ${variable()} is an option too, but harder to implement efficiently. Zope's TAL has nocall: modifier that makes functions returned as objects. Perhaps PHPTAL could have the opposite that makes all closures automatically executed? ${call:variable} I've used simple variable in the examples, but I expect more complex cases to work as well: $phptal-array = array('closure'=function(){ return new Object(); }); ${call:array/closure/objects_property} etc. ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] Support for PHP 5.3 closures
Ok, I see. Certainly native properties access are faster than using the magic __get() method, although I would guess that for the kind of loops in templating logic, the difference would be totally negligible. So I would opt for a change to the context class, and access all properties by the magic __get() method, storing the actual values in a protected associative array. It won't be as fast as the current implementation in synthetic benchmarks but I don't think it'll make any difference in real world usage. Anyway, if a custom syntax is decided I think that the best alternative is using a call: modifier, but which was optional when using multiple level paths. In example: ${closure} - $this-closure ${call:closure} - $this-closure() ${closure/foo} - $this-closure()-foo ${call:closure/foo} - $this-closure()-foo() So basically the call modifier just operates over the last segment of the path. Previous segments being closures would be automatically executed by Context::path(). By the way, reviewing the Context.php code I noticed the following lines: public function __get($varname) { if (property_exists($this, $varname)) { // must use property_exists to avoid calling own __isset(). return $this-$varname;// edge case with NULL will be weird } Since __get() is only called by the PHP engine when no public property is found in the object, the property_exists() condition would only make sense to retrieve private/protected properties, which I don't think it's a desired outcome. regards, /imv On 12/23/09 8:17 PM, Kornel Lesinski wrote: On 23 Dec 2009, at 18:27, Iván Montes wrote: I fail to see why checking for closures makes variable access much slower. As far as I remember, interpolated variable paths are compiled to use the $ctx-path() method, and it already does quite a few type checking logic already. Checking for a closure basically would mean adding instanceof conditions, being instanceof an operator and as such extremely fast, I don't see why it should hurt overall performance. First path of component is optimized to be $ctx-var which reads value directly from a property of $ctx object. For simple cases like ${variable} no function is called at all (not even __get()). Without any extra syntax, it's not known at compilation time whether variable will be real value or a closure, so I won't be able optimize those checks away. ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] Advanced TALES
After looking at the wiki page examples, couldn't we solve this with specialized tales modifiers? option tal:repeat=opt options tal:attributes=selected equals: opt, selected_option/ tr tal:repeat=row rows tal:attributes=class ternary:repeat.row.odd, 'odd', 'even'/ It's a bit more verbose but they are quite declarative and should be easy to implement in the current PHPTAL infrastructure. /imv On 11/17/09 2:05 PM, Kornel Lesiński wrote: On 17-11-2009 at 12:35:02 Marco Pivetta ocram...@gmail.com wrote: I know it's not an elegant solution, but it's a solution and I already use it: what about tal:define? It is already possible to fix those tales problems wrapping content within a tal:omit-tag-ed definer element or directly a tal:define block. I don't understand how does it help. If you have selected_id variable and want to select option with that ID, how would you do it with tal:define? without help of php: modifier? even/odd classes can be done with pure TALES and tal:omit-tag, but it's ugly: tr class=even tal:omit-tag=repeat/row/odd tr class=odd tal:omit-tag=repeat/row/even /tr /tr I'm probably loosing the point of the discussion, but I don't really see any reason to make the syntax more complex and also a bit heavyer to compute for the parser... This would be heavier only once during template compilation, so performance is not a problem. ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] PHPTAL prefilters
On 9/16/09 4:56 PM, Kornel Lesiński wrote: On 16-09-2009 at 14:45:39 Iván -DrSlump- Montes drsl...@pollinimini.net wrote: // Get the standard instance of the loader $loader = $tpl-getFilterLoader(); // and add a new location for filters $loader-addPrefixPath('My_Filter', '/path/to/my/filter'); I'm afraid it doesn't save much work compared to setting prefilter objects directly - you still have to load, instantiate and set a class, just a different one this time. Correct but the point is that it separates concerns among different classes. PHPTAL is the coordinator while FilterLoader takes care of loading filters. This way I could easily change the filters used when running unit tests for example. Besides, it improves code re-use in my opinion, I can have filters which are used among all the company's projects and specific filters for my project. And overriding of implementations wouldn't be easy with template caching. Without loading of filters, I wouldn't know which ones were overridden since template was cached, and of course loading of prefilters every time is the thing we want to avoid. I'm not too fond in how the caching works so I might be completely wrong here. Why are prefilters needed to compute the caching logic? As I understand it, the filters are run at compile time not at run/rendering time. // or, setup PHPTAL with our custom loader $tpl-setFilterLoader( new Zend_Loader_PluginLoader() ); I probably could support optional use of Zend's loader. That would require little code on PHPTAL's side. I wouldn't recommend it, it'll add another dependency (although optional) to PHPTAL which was I was trying to avoid in the first place. Using only the autoloader/include_path might be a little limiting in my opinion. It would make it harder to replace a standard filter class for example. Why would you want to do that? I am planning to ship some standard prefilters with PHPTAL (like removal of whitespace or comments), but if someone doesn't want them, why wouldn't he simply use addPreFilter(my_better_whitespace_remover)? That's the whole point of using the loader pattern. Instead of manually overriding the filter in the code, the loader would allow to use different whitespace removers filters based on the instantiated loader. So I can use a dummy filter for development (no whitespace removed) and a very aggressive one in production. For just one filter the benefits are not clear but once you start adding filters I think they become obvious. Besides, implementing a simplified plugin loader wouldn't be that difficult and it would allow to use it in other parts of PHPTal in the future, for example, to override the default implementation of standard namespaces, tales modifiers ... Standard namespaces and modifiers have clearly defined behavior. I'd rather not let users override that, as this could let them create standard-looking templates that don't work as documented. It also makes it harder for PHPTAL to optimize code generation. It would however be nice to ease adding of your own namespaces and modifiers. While I agree that encouraging the change of standard functionality is not a good idea at all, as an application developer I would like to have the possibility to do it, if I absolutely need to, in a clean way. Instead of hacking PHPTAL to add my custom code I could have a clean interface to add my own logic, and only me would be responsible for that. Of course I'll need then to double check my changes when I want to upgrade the PHPTAL version but I will not have avoided a branched version of the library. Finally, I'm not implying that this is the only possible way to implement this. It's just a common pattern used in other projects which works quite well when having a few dependencies (filters in this case) and also when having a lot of them. regards, /imv ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal
Re: [PHPTAL] PHPTAL prefilters
On 9/16/09 6:03 PM, Kornel Lesiński wrote: On 16-09-2009 at 16:30:35 Iván Montes drsl...@pollinimini.net wrote: I'm not too fond in how the caching works so I might be completely wrong here. Why are prefilters needed to compute the caching logic? As I understand it, the filters are run at compile time not at run/rendering time. Whenever prefilters change, template has to be recompiled (or rather different cache copy needs to be used), otherwise change won't make any effect. For example if your regular code compiles template with prefilter, and then you'll change prefilter implementation in unit test, unit test will still use copy cached by regular code. Right, however I think that it's something the developer should be aware of and handle herself. Filters are going to change on the development environment so the developer should either disable caching alltogether in that environment or flush it when she changes a filter. Besides, couldn't the loader configuration be added to the cache hashing algorithm, that would solve the problem. Although, in my opinion, the developer should invalidate the cache manually or disable it if she changes the filters. While I agree that encouraging the change of standard functionality is not a good idea at all, as an application developer I would like to have the possibility to do it, if I absolutely need to, in a clean way. When do you need to and how? I'm aware that phptal:cache needs to be configurable, but that's rather exceptional. I don't see why anybody would override tal:content attribute, not: modifier and such. The first thing that pops to mind is to create a proxy around the standard handler to do rather trivial tasks like logging, profiling or change the damn long structure modifier for something shorter :) However I don't have an strong use case now and honestly I can't easily think of one, it's obvious however that there are many hardcoded dependencies between PHPTAL and its standard handlers which could be replaced with just one dependency with the loader. It just feels better at the design level. regards, /imv ___ PHPTAL mailing list PHPTAL@lists.motion-twin.com http://lists.motion-twin.com/mailman/listinfo/phptal