Hi everyone,
the first stable version of OPT 2 hasn't been released yet, but for some time I've been thinking about various ideas that could be implemented in the next branch. You should not be surprised. I am far away from claiming that OPT 2.0 will be absolutely brilliastic fantastic the best template engine/presentation framework in the world, because I perfectly know that there will be always things that can be improved. So when the feature list of 2.0 version was frozen three months ago, the new ideas were thrown on a TODO list. Now it's time to publish them. First of all, I would like to thank everyone for your submissions - most of the ideas came from you or your expectations published here or somewhere on the Internet.
The general model of OPTCurrently, OPT term means both the presentation layer framework and the template language used by it. Although it is widely extensible, it is still OPT. There are some other XML template languages available around. One of them is
TAL - together with
METAL can be easily implemented in the current OPT, but the expression language,
TALES must be abandoned here. There is one more problem - OPT template language is quite well documented, but does not exist as a fully separate product.
Here is the point - some people have great ideas about the XML language or want to port an existing one. Unsually, they must reinvent the wheel, write their own XML parser, invent the whole API etc. etc. On the other hand, the future can bring us people that would like to see the OPT language on different platforms.
Separation of the template language and the template compilerIn the 2.1 branch, you will be able to use the template compiler to implement your own XML template language from scratch. OPT will give you the necessary tools - the parser, PHP code linker and a modern objective API for the end users. Of course, the existing template language will be still available by default (and please don't worry - I'm not going to throw it away :)). The change will make no harm the programmers that use OPT in their applications and in fact they should not even see the difference, but the project will be much more flexible. The expression engine will become a module; the programmers may write new ones for special purposes or as a replacement.
On the other hand, the template language will get its own name, specification and all this stuff. It will be the default XML template language available in OPT 2.1, but then there will be absolutely no problem to port also the whole
TAL, including
TALES etc.
Changes in the parseable attribute supportSome of the instruction attributes accept OPT expressions, like:
<opt:attribute name="$attrName" value="$attrValue" />
If we want the name to be a string, we do not need to add the second quotation which is very ugly. We can deal with this by changing the namespace to
str:<opt:attribute str:name="foo" value="$attrValue" />
This model is not very flexible and makes some practical problems with the XML schemas and other stuff. Nowaker also suggested that writing the namespace first also can be confusing, especially in the
IMG tags. We've got used to write
src after them, but if we need a dynamic image address, we suddenly have to deal with
parse:src which is less intuitive and leads to small, but annoying mistakes.
Now, I'm going to make modular expression systems, so the implementation must be more flexible. This gives a great opportunity to solve these problems once and for all. Namespaces are the main source of them, so the system must stop using namespaces. So the last possibility is to use the attribute values, for example:
<opt:attribute name="src:foo" value="$attrValue" />
The same thing could be applied to the "dynamic" HTML tags, but here I need still some time to check if it does not make further problems:
<img src="parse:$foo" />
Of course the namespaces will remain for
backward compatibility.
Changes in the variable escaping and data filteringCurrently, there are two modifiers that suggest the template compiler to turn on or off the HTML escaping in the expressions:
{e:$variable} - "entitize" the HTML special chars in the variable.
{u:$variable} - DO NOT "entitize"
The same Nowaker suggested the possibility of changing the default escaping function from
htmlspecialchars() to something else and this has already been implemented in OPT 2.0. However, sometimes we need different escaping systems for different purposes (i.e. the attributes should have a bit different one). In the 2.1 branch, we will be able to register our own modifiers:
{e:$variable} - use the default escaper
{a:$variable} - use the secondary escaper
{u:$variable} - disable the escaping
etc.
In the proposal we need to pay attention on
opt:root and
opt:extend tags that can also control the escaping, as well as the OPT configuration.
Improvements of the the template language1. To add the XSLT style of the conditional instructions, like:
<opt:if test="$foo">
<opt:main>
The main choice.
</opt:main>
<opt:else>
The alternative choice.
</opt:else>
</opt:if>
Of course, the current style will not be thrown away. Both of the styles can be used together in the same template without any magic switches etc. The tag names may be changed. Thanks to Nowaker for the suggestion.
2. Minor naming changes. Don't you think that the name of
opt:on attribute is very confusing for the users that do not know what it really does? I don't want to change it in OPT 2.0, because the feature list is frozen and this attribute is quite useful. But in OPT 2.1 we could give it the name
opt:skip-tag or something like that and make an alias
opt:on for backward compatibility purposes.
3. The improvements of the
opt:content tag. In one of my recent projects I encountered the following problem. I had a list of product parameters and some of them could be null. I wanted to display
Not set, if the value is null or to show the value in the opposite case, so I wrote the following code:
<td opt:content="$item.end_time">Not set</td>
However, in two cases I was forced to use the ordinary IF.
a) I was displaying a number and wanted to append the units:
<td opt:content="$item.time_limit">Not set</td>
I cannot write
opt:content="$item.time_limit~' seconds'" because the condition will always fail. Now the only solution is:
<td><opt:if test="$item.time_limit">{$item.time_limit} seconds<opt:else>Not set</opt:else></opt:if></td>
In OPT 2.1 you will be able to write:
<td opt:content="$item.time_limit" opt:append="str: seconds">Not set</td>
b) If we want an extra formatting:
<td opt:content="$item.date">Not set</td> <!-- how to add the date formatting? -->
Also, currently the only solution is the
opt:if instruction. In OPT 2.1:
<td opt:content="$item.date" opt:display="date('d.m.Y H:i', $item.date)">Not set</td>
Note that this can be also used to solve the previous problem.
4. New XML operation attributes:
a)
opt:tag-name - allows to create a dynamic tag name.
<div opt:tag-name="$tagName">
b)
opt:attributes - reads the tag attributes from an assotiative container[/i]:
<div opt:attributes="$extraAttributes">
Please note that this can be easily achieved with the following construct in OPT 2.0:
<div>
<opt:attribute name="$extraAttributes.name" value="$extraAttributes.value" opt:section="extraAttributes" />
</div>
5. Perhaps some improvements of the components (the interface should not change - I don't see the reason why it should), but it depends on the initial implementations of
Open Power Forms - I must see what we need there. However... the component model in OPT 1.1 was evil but worked perfectly with OPF 1 :).
Expression language improvements1. We can check the existence of a value in a container with the
contains() function. Destroyed suggested a long time ago to make an operator for this operation. I liked the idea, but the implementation was much harder. Now I've found a way to implement this and the new expression parser will introduce the
contains operator:
<opt:if test="$box contains 'block'"> ... </opt:if>
Maybe some other nice operators will appear?
2. Backtick syntax improved - again, because of the same idea it is possible to improve the backtick syntax. Currently, we are not able to concatenate the source backtick text with a variable. The following code concatenates the variable with
the result of the backtick transformation:
{`Hi everyone`~$foo}
Extreme pointed out that such feature would allow to make a much nicer gettext internationalization, for example:
{`Hi, `~$user.name~`, you have written `~$user.article_count~` articles`}
My suggestion is:
{`Foo `~$bar} - the variable is appended to the SOURCE text, before the backtick transformation
{(`Foo `)~$bar} - the variable is appended to the transformed text
So, the source text is concatenated with the things within the same translation unit (the same bracket nesting level).
3. Writing to the non-array containers - will be possible because of the same implementation tricks:
{$container.variable is 'foo'} - works with arrays, will work with objects
In fact, maybe the idea of containers will be more standarized?
4. Dynamic item name in the containers, an equivalent of
$foo[$id] in arrays. I look for syntax suggestions :).
Issues related to the template language standarizationThe template language specification must be portable and do not rely on PHP. In fact, it IS portable even now, if we follow the guidelines and do not throw any @#$%@#$ like OOP to the templates. The status of the following parts will surely change:
1. OOP syntax in expressions
$foo::method() - will not be a part of the official specification, but a language extension provided by the very PHP implementation.
2. Array syntax in expressions:
$foo[$id] - like above.
3. Any other references to PHP will receive the same status.
4. It is possible that the template language will use a different namespace, but of course the old will remain for the
backward compatibility purposes.
Please note that you will be able to disable all the "language extensions" :).
The goal is to develop a multi-platform, semi-declarative XML application for writing the view templates that supports a wide variety of tasks that need to be solved in the presentation layer. Why?
- TAL is too simple for some more advanced tasks (i.e. I cannot imagine the advanced form processing or grid displaying, although probably it is possible).
- XSLT is powerful enough, but it is a functional language and has the same problem, as the imperative languages, like PHP, Smarty syntax etc. - if you encounter a particular problem, you have to implement the solution manually. Fortunately, the code in the functional language is much more reusable... moreover, the script data handling is very problematic.
- Curly bracket syntax sucks and reinvents the wheel :).
To sum upAs you see, there are many things that can be improved and I'm going to improve them to give you better and better product. Some recent and critical user suggestions have already been implemented in OPT 2.0 branch or will be implemented before the beta3 release. However, there is a chance that some of the features listed here may appear in 2.0.x versions, for example the improvements of the
opt:content attribute. The implementation of the 2.1 branch will begin right after the release of the 2.0.0 version, now it's time for planning.