speedmax / h2o-php Goto Github PK
View Code? Open in Web Editor NEWA beautiful template engine for PHP in Django style
Home Page: http://www.h2o-template.org
A beautiful template engine for PHP in Django style
Home Page: http://www.h2o-template.org
I have an object with child objects that have their own methods. According to the documentation, these should be callable via the dot notation, should they not?
Example:
{% for index, object in c.objects %}
object.method_name returns a string, but it's not appearing in the rendered page?
Hi there...
Cant seem to get relative_date and relative_time to work with integer timestamps.
E.g. {{ mytime|relative_time }} where mytime is an integer timestamp always returns the current date / time.
I can see why. In filters.php line 250:
$timestamp = strtotime($timestamp);
Maybe this should be:
$timestamp = (!is_numeric($timestamp)) ? strtotime($timestamp) : $timestamp;
And, line 278:
$time = strtotime($time);
Should be:
$time = (!is_numeric($time)) ? strtotime($time) : $time;
Cheers!
This ticket has 0 attachment(s).
This looks like a string encoding issue for gettext processing, some latin character is broken when html is set to UTF8 but works fine without it.
This ticket has 0 attachment(s).
The nl2br filter does not work anymore, because the autoescape feature convert it to a literal
tag.
As current workarround, I've figured I can use:
{{ tagname | escape | nl2br | safe }}
But I find this a bit cumbersome. Would it be possible to find a better fix for this? (e.g. how django does it?)
I don't know much php but ... in loaders.php
the class H2o_File_Cache constructor may create a directory using 'tempnam' which is not done securely(as far as I know it is not secure in php :/ ).
Using the ORM framework found at: http://lukebaker.org/projects/activerecord-in-php/ I was unable to output data in the template because the model’s object’s "attributes" array (where it keeps its row data, accessed through a custom getter __get()) was protected.
In the PHP file, if I have a $user object, I can do print $user->username and it will output "bob", but if I display a template, with vars "user" => $user ... and then try to {{ user.username }} in template, nothing is output.
This ticket has 0 attachment(s).
When a VariableNode()
resolves an object, it is not printed as string.
This could be done using the __toString()
method.
Where could this be implemented?
The source was a bit unclear for me, whether that needs to happen in resolve()
, getVariable()
or escape()
While testing the library, I noticed this error when loading the h2o-php/example/i18n/index.php page:
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'The for tag cannot iterate over the value: ' in h2o-php/h2o/tags.php:137
Stack trace:
#0 h2o-php/h2o/nodes.php(27): For_Tag->render(Object(H2o_Context), Object(StreamWriter))
#1 h2o-php/h2o/tags.php(172): NodeList->render(Object(H2o_Context), Object(StreamWriter))
#2 h2o-php/h2o/nodes.php(27): For_Tag->render(Object(H2o_Context), Object(StreamWriter))
#3 h2o-php/h2o.php(136): NodeList->render(Object(H2o_Context), Object(StreamWriter))
#4 h2o-php/example/i18n/index.php(44): H2o->render(Array)
#5 {main}
thrown in h2o-php/h2o/tags.php on line 137
The issue happens because the index.php contains an empty array() for one of the user.tasks (3rd). The error does not happen if the array is not empty.
From version:
commit 93eee9c
I can't find any example but i think it must be possible somehow.
Also, what about array literals?
What i am looking for is
{{ myClass.someMethod(['a' = 'b', 2, 3, 4]) }}
I assign my objects via render()
. I can {% debug %}
them, just not call any method.
I thought about making "MyClass" a filter collection, but then it is still not clear if i can set arrays inside the template to use them as option hashes. And it would be bad for a couple other inheritance related reasons.
Is this planned or already supported?
The following piece of code creates a notice if there is was no limit or reversed value matched. This is kind of sloppy, and is causing me trouble because it throws an ErrorException
in my code.
class For_Tag
@list(,$this->key, $this->item, $this->iteratable, $this->limit, $this->reversed) = $match;
For a quick fix I just pushed two false values onto $match
before this line is called. But perhaps you could use named subpatterns with the preg_match
, then do:
if (isset($match["limit"]))
$this->limit = (int) $match["limit"];
else
$this->limit = 0;
echo $h2o->render(array(
’org’=>’My People’,
’job’ => ’templater’ ,
’days’ => $arr ,
));
In the above example the var named "org" fails to show and chucks up 4 warnings, below, xdebug output.
Change the var name to "porg" and all works as it should !
It is repeatable with the word "andy" as well.
Call the var "andy", it fails, "randy" it works.
However, "indy" works fine, so it not because it starts with a vowel.
Sorry I couldn’t fix it but I think you might find that a parser is sensing the words ’or’ and ’and’ as being one of the permitted tags/filters.
I couldn’t spot it though.
A very subtle bastard of a bug, lost half a day, but am gratified if it helps you.
Win32, server2003, apache 2, PHP5.2.6.
Paul
Notice: Undefined offset: 0 in C:\var\www\includes\h2o\h2o\context.php on line 92
Call Stack
1 1.0543 121392 {main}( ) ..\index.php:0
2 1.0999 1002640 H2o->render( ) ..\index.php:291
3 1.1005 1003872 NodeList->render( ) ..\h2o.php:133
4 1.1005 1003928 Extends_Tag->render( ) ..\nodes.php:27
5 1.1006 1004040 NodeList->render( ) ..\tags.php:200
6 1.1007 1004672 VariableNode->render( ) ..\nodes.php:27
7 1.1007 1004944 H2o_Context->resolve( ) ..\nodes.php:59
( ! ) Warning: preg_match() expects parameter 2 to be string, array given in C:\var\www\includes\h2o\h2o\context.php on line 102
Call Stack
1 1.0543 121392 {main}( ) ..\index.php:0
2 1.0999 1002640 H2o->render( ) ..\index.php:291
3 1.1005 1003872 NodeList->render( ) ..\h2o.php:133
4 1.1005 1003928 Extends_Tag->render( ) ..\nodes.php:27
5 1.1006 1004040 NodeList->render( ) ..\tags.php:200
6 1.1007 1004672 VariableNode->render( ) ..\nodes.php:27
7 1.1007 1004944 H2o_Context->resolve( ) ..\nodes.php:59
8 1.1047 1006256 preg_match ( ) ..\context.php:102
( ! ) Warning: preg_match() expects parameter 2 to be string, array given in C:\var\www\includes\h2o\h2o\context.php on line 106
Call Stack
1 1.0543 121392 {main}( ) ..\index.php:0
2 1.0999 1002640 H2o->render( ) ..\index.php:291
3 1.1005 1003872 NodeList->render( ) ..\h2o.php:133
4 1.1005 1003928 Extends_Tag->render( ) ..\nodes.php:27
5 1.1006 1004040 NodeList->render( ) ..\tags.php:200
6 1.1007 1004672 VariableNode->render( ) ..\nodes.php:27
7 1.1007 1004944 H2o_Context->resolve( ) ..\nodes.php:59
8 1.1087 1006408 preg_match ( ) ..\context.php:106
( ! ) Warning: array_shift() [function.array-shift]: The argument should be an array in C:\var\www\includes\h2o\h2o\context.php on line 164
Call Stack
1 1.0543 121392 {main}( ) ..\index.php:0
2 1.0999 1002640 H2o->render( ) ..\index.php:291
3 1.1005 1003872 NodeList->render( ) ..\h2o.php:133
4 1.1005 1003928 Extends_Tag->render( ) ..\nodes.php:27
5 1.1006 1004040 NodeList->render( ) ..\tags.php:200
6 1.1007 1004672 VariableNode->render( ) ..\nodes.php:27
7 1.1126 1005800 H2o_Context->applyFilters( ) ..\nodes.php:61
8 1.1127 1006928 array_shift ( ) ..\context.php:164
This ticket has 0 attachment(s).
I've been using h2o templates to build up a website. However, I have been building the page normally as I would do and just putting in a terms and conditions page which has a lot of text and basic html characters etc...
However, when I reach a certain number of characters it breaks with the error logs stating
Unclose tag, expecting endblock --- Triggered from /var/www/public_html/config/lib/h2o/parser.php:98
If I reduce the text of the file back down it works, does anyone have any ideas of what is going on and how we can fix this issue.
Don't have time to fork and push right now, but before I forget...
line 173 of /h2o/parser.php:
From:
self::$name = '/[a-zA-Z][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*/';
To:
self::$name = '/[a-zA-Z_][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*/';
'### base.html
<html>
<head><title>{% block title %}OHH NOES!{% endblock %}</title></head>
<body>
<div id="main">{% block body %}{% endblock %}</div>
</body>
</html>
'### one_col.html (notice no title block)
{% extends "base.html" %}
{% block body %}
<div id="col1">{% block content %}{% endblock %}</div>
{% endblock %}
'### report.html (notice title block)
{% extends "one_col.html" %}
{% block title %}Awesome Report{% endblock %}
{% block content %}I love H2O!{% endblock %}
'### view-source: http://www.example.com/report.html
<html>
<head><title>OHH NOES!</title></head>
<body>
<div id="main">
<div id="col1">
I love H2O!
</div>
</div>
</body>
Warning: unserialize(): Function spl_autoload_call() hasn't defined the class it was called for in h2o/loaders.php on line 108
I looked into it, but don't understand how unserialize() uses spl_autoload_call() and which class should be defined. In fact, I don't get the warning at all, because unserialize() is a global function, so why is there a need to define a class?
Full stack trace below. H2o version is 0.4.1.
( ! ) Warning: unserialize(): Function spl_autoload_call() hasn't defined the class it was called for in h2o/loaders.php on line 108 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0002 | 245648 | {main}( ) | ../index.php:0 |
2 | 0.0118 | 1005480 | H2o->__construct( ) | ../index.php:9 |
3 | 0.0123 | 1010792 | H2o->loadTemplate( ) | ../h2o.php:85 |
4 | 0.0123 | 1010856 | H2o_File_Loader->read_cache( ) | ../h2o.php:90 |
5 | 0.0134 | 1024048 | unserialize ( ) | ../loaders.php:108 |
current these two methods are declare as private, they should change to protected so, its easier for subclass to reuse those methods
This ticket has 0 attachment(s).
Is it possible to use a Filter within an if tag? e.g.
{% if people | length <= 1 %}
There is only one person
{% else %}
There is more than one person
{% endif %}
Assume the following:
$arr = array(
array('x' => 0),
array('x' => 1),
array('x' => 2),
array('x' => 3),
);
$b = array(1, 2, 3, 4);
{% for a in arr %}
{{ b.{{ a.x }} }}
{% endfor %}
Expected output:
1
2
3
4
Actual output: unexpected character in filters : "." at 306 on line 228 in /h2o/h2o/parser.php
(edited to clarify variable tags)
When I try to use the {% comment %}
tag, I get an error it does not exist.
Currently i18n only supports gettext native php extension, it is good but contains serious limitation on some deployment platform.
For instance apache1/2 caches translation mo file aggressively with no way to flush the gettext cache when apache is setup with mod_php, (php fastcgi is not affected)
Ideal gettext support
This ticket has 0 attachment(s).
I'm sorry if I'm nitpicking here, but I would like a strftime filter in addition to the date filter (I like strftime's syntax more and strftime works with locales).
Could it be added?
I found that running a template code such as:
{% blocktrans test=value_from_php %}This is a {{ test }}!{% endblocktrans %}
where value_from_php is a value passed in the render() method, with empty string.
The output of this is:
This is a %(test)!
meaning it does not replace the string within the translation text.
It's missing a static declaration, so here it is:
Index: h2o/parser.php
--- h2o/parser.php Mo Nov 17 05:01:46 2008
+++ h2o/parser.php So Jun 5 00:18:47 2011
@@ -148,7 +148,7 @@
static $whitespace, $seperator, $parentheses, $pipe, $filter_end, $operator,
$number, $string, $i18n_string, $name, $named_args;
- function init() {
+ static function init() {
$r = 'strip_regex';
self::$whitespace = '/\s+/m';
Hi,
when iterating over an array, the indexes are not kept:
$someArray = array(3=>"Three", 1=>'One',0=>'Zero Mostel', 2=>'Two');
If you're now iterating the array like this:
{% for key,value in someArray %}
{{key}}: {{value}}<br />
{% endfor %}
you get the following:
0: Three
1: One
2: Zero Mostel
3: Two
while this is expected:
3: Three
1: One
0: Zero Mostel
2: Two
Maybe using sort() instead of asort() somewhere?
The class H2o_File_Loader that extends H2o_Loader tries to use a private property from H2o_Loader, giving the alarm:
Notice: Undefined property: H2o_File_Loader::$cache in /var/www/h2o/h2o/loaders.php on line 50
To solve the problem, just change the line 11 of loaders.php:
private $cache = false;
to:
protected $cache = false;
This is so small issue the I figured it wasn't worth to fork your code.
Very nicely done! I was looking for something Django alike to deal with templating... the alternatives, sad to say, suck!
Cheers,
The with block does not seem to work.
e.g. {% with form as f %}{% debug %}{% endwith %}
produces an empty structure, while {{ form.url }}
does work.
Hello,
I tried to load template via dict_loader, however, it generated:
PHP Fatal error: Call to undefined function dict_loader()
Hi there...
If I have a variable (say "my_timestamp") containing an integer timestamp, the following {{ my_timestamp | date }} does not work (it always displays Jan 1 1970).
The current code for this filter passes integers to strtotime, but that returns FALSE for integer input (at least on my system, php 5.3).
static function date($time, $format = ’jS F Y H:i’) {
if ($time instanceof DateTime)
$time = (int) $time->format(’U’);
return date($format, strtotime($time));
}
I would suggest this should be:
static function date($time, $format = ’jS F Y H:i’) {
if ($time instanceof DateTime)
$time = (int) $time->format(’U’);
if (!is_numeric($time)) $time = strtotime($time);
return date($format, $time);
}
This ticket has 0 attachment(s).
I don't see a good reason for variables on template be case sensitive.
A issue example:
When get data from a database, append this data to a collection of objects (that map some database table) and then send this array of objects to h2o template, all the properties of my current object must respect the case sensitive to work properly. Unfortunately some times, change the case of table column name is necessary and it will make the h2o page brake, without either a warning or error message. The reason is because that column name (a property of object) was previously wrote with a different case.
Trying to create customized filters:
class CustomFilters extends FilterCollection {
function contains($haystack, $needle) {
return strpos($haystack, $needle) !== false;
}
}
I get this error message:
[E_STRICT] call_user_func_array() expects parameter 1 to be a valid callback, non-static method CustomFilters::contains() should not be called statically in /home/bruno/workspace/libs/h2o-php/h2o/context.php on line 197
Solved by forcing the function as static (exactly the opposite what the error reported):
class CustomFilters extends FilterCollection {
static function contains($haystack, $needle) {
return strpos($haystack, $needle) !== false;
}
}
Any ideas why this weird behaviour? And, if that's the correct solution, it would be nice idea to update the Wiki documentation.
Thanks,
I'm getting this error (on some server setups):
Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/tmp/9Z9Ngp) is not within the allowed path(s): (/home/www/web362/) in /home/www/web362/html/wordpress/wp-content/plugins/password-protect-wordpress-blog/lava/_classes/h2o/loaders.php on line 181
Warning: realpath() [function.realpath]: open_basedir restriction in effect. File(/tmp) is not within the allowed path(s): (/home/www/web362/) in /home/www/web362/html/wordpress/wp-content/plugins/password-protect-wordpress-blog/lava/_classes/h2o/loaders.php on line 190
Warning: file_put_contents(/h2o_0568baaca511328a453079f08744fa99) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web362/html/wordpress/wp-content/plugins/password-protect-wordpress-blog/lava/_classes/h2o/loaders.php on line 208
Is there a way to disable the cache or tell it to store it somewhere else rather than a temp directory (which it doesn't have the permission to create). I see that cache_dir is a option but I can't see how I can pass an options array without changing your code. The function which creates and returns the file loader only takes one parameter - maybe this needs to be changed to support a second parameter ($options - which would default to a blank array).
Template code:
{{ myvariable|nl2pbr }}
Results in:
Fatal error: Call to undefined function h2o_nl2br() in h2o/filters.php on line 218
This ticket has 0 attachment(s).
Intermittent problem which is hard to nail down, only affects single-line comments AFAICT. {* a comment *}
example:
@@@
{% extends ’gmap_layout.html’ %}
{%block title %}{{ service.title|excape }} in {{ place_name }}{% endblock %}
{% block header %}
Information about your chosen place more ...
{% endblock %}
@@@
PHP Warning shown:
Warning: Missing argument 2 for H2o_Node::__construct(), called in C:\var\www\includes\h2o\h2o\parser.php on line 80 and defined in C:\var\www\includes\h2o\h2o\nodes.php on line 8
Call stack:
1 0.9379 129168 {main}( ) ..\index.php:0
2 1.0018 1277784 H2o->__construct( ) ..\index.php:292
3 1.0071 1280568 H2o->loadTemplate( ) ..\h2o.php:83
4 1.0071 1280568 H2o_File_Loader->read_cache( ) ..\h2o.php:87
5 1.0090 1299704 H2o_File_Loader->read( ) ..\loaders.php:59
6 1.0101 1300656 H2o->parse( ) ..\loaders.php:47
7 1.0230 1465704 H2o_Parser->parse( ) ..\h2o.php:103
8 1.0235 1467360 H2o::createTag( ) ..\parser.php:88
9 1.0236 1467928 Extends_Tag->__construct( ) ..\h2o.php:148
10 1.0238 1469568 H2o_Parser->parse( ) ..\tags.php:176
11 1.0406 1474472 H2o_Node->__construct( ) ..\parser.p
Workround:
1 hide php warnings ;-)
2 call a second template beneath it.
$footer = new h2o( ’tpl/footer.html’);
echo $footer->render();
Win32, php 5.2.6, h20 beta 3
This ticket has 0 attachment(s).
When I try to run the i18n example (/h2o/example/i18n/) I get a whole bunch of Strict Standards errors:
Strict Standards: Non-static method H2o_I18n::gettext() cannot be called statically in /h2o/h2o.php on line 227
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Only variables should be passed by reference in /h2o/ext/i18n.php on line 331
Strict Standards: Non-static method H2o::getOptions() should not be called statically in /h2o/ext/i18n.php on line 361
Strict Standards: Non-static method H2o::getOptions() should not be called statically in /h2o/ext/i18n.php on line 361
Strict Standards: Non-static method H2o::getOptions() should not be called statically in /h2o/ext/i18n.php on line 361
Strict Standards: Non-static method H2o_I18n::gettext() cannot be called statically in /h2o/h2o/context.php on line 199
Strict Standards: Non-static method H2o_I18n::gettext() cannot be called statically in /h2o/h2o/context.php on line 199
And of course the example doesn't work.
*.mo files do get generated though.
PHP version: 5.2.10
This ticket has 0 attachment(s).
Strict standards: Non-static method CoreFilters::first() cannot be called statically in /home/tkn/public/h2o-php/h2o.php on line 211
This ticket has 0 attachment(s).
If you create a template:
{% extends base.html %}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id consequat justo. Phasellus gravida, mi a aliquam eleifend, nisi quam elementum felis, eget congue magna lorem eget magna....
... REPEAT FOR A LONG TIME...
{% block content %}
{% endblock %}
The block and endblock tags are not interpreted but are shown in the output as raw tags. If you move the block to the top of the file the block shows correctly.
It seems like there's a maximum number of characters allowed in the templates.
Will we see it? I mean it has some powerful changes, and a template engine could make much use of it :)
relative_time doesn't work when the timestamp given is in the future. i've fixed it in my versions. since i don't have permissions to edit the source, i'm posting the change below..
static function relative_time($timestamp, $format = 'g:iA') {
...
if($delta < 0){
$delta = abs($delta);
$future = 1;
}
...
if($future)return "in $string";
else return "$string ago";
}
Hi there...
Just downloaded the latest from github (0.4)... Got this error:
(2048) Non-static method H2O_RE::init() should not be called statically, assuming $this from incompatible context /Volumes/Work/www/sites/testsparks.com/modules/Sparks.View/ext/h2o/h2o/parser.php (185)
Cheers...
This ticket has 0 attachment(s).
When template tags are indented with the HTML code, the HTML tags get double indention. I find this output ugly, and would like to see it differently.
I think the following would lead to much to both clean template code and clean output.
I hope you agree :)
You should check the files and insert in top of all:
defined('DS') or define('FILE_DIR', dirname(__FILE__));
then change all the:
`````` dirname(FILE).DS.to:
FILE_DIR.DS.```
In "filters.php" file on the line 125 it should be "MB" instead of "BM":
'BM' => pow(2, 20), 'GB' => pow(2, 30),
should be transformed in
'MB' => pow(2, 20), 'GB' => pow(2, 30).
I noticed that the text in blocktrans is not being properly handled due to excessive escaping.
To reproduce the problem:
the template file:
{% blocktrans %}Didn't get it? <a id="resend" href="#">Resend</a> now{% endblocktrans %}
{%blocktrans %}Reply with "{{ keyword }}" to {{ code }}{% endblocktrans %}
the .mo file result:
msgid "Didn't get it? <a id=\\\"resend\\\" href=\\\"#\\\">Resend</a> now"
msgstr "¿No lo ha recibido? <a id=\"resend\" href=\"#\">Reenvíelo</a> ahora"
msgid "Reply with \\\"%(keyword)\\\" to %(code)"
msgstr "¡Envíe un SMS con \"%(keyword)\" al %(code) para confirmar!"
This causes the translation string to be untraceable for replacing in the original template when the page is rendered.
When applying named argument to filters, when use a variable as name:value pair, the variable is not resolved with the given context.
could be the it be Parser or Context::applyFilters()
This ticket has 0 attachment(s).
Since h2o is based on Django templates, why did you choose to rename some of the loop variables?
Django:
{% for item in list %}
{{ forloop.counter0 }}
{{ forloop.parentloop.counter0 }}
{% endfor %}
h2o:
{% for item in list %}
{{ loop.counter0 }}
{{ loop.parent.counter0 }}
{% endfor %}
This makes templates non-portable (or less portable)
The links_to filter by default outputs escaped HTML code. Please mark it as safe.
autoescape all variable output will improve security against XSS attacks and script injections.
This ticket has 0 attachment(s).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.