Comments (5)
Your question is not improper, and thanks again for your interest.
Reason are:
-
avoid notices when a variable is undefined. Inside a template, the usage of
$my_var
produces a notice if it not defined.$this->my_var
doesn't. So a secure use of scoped var is:isset($my_var) ? $my_var : ''
that is more typing than
$this->my_var
. Actually, the benefit of less typing in scoped var, just vanished. -
Autoescape. Foil supports autoescape for variables. Sure it is not as powerful as it is in compiled languages (unless you use arraization), but I feel that something is better than nothing. More on the topic.
If you are intersted in a more in depth comparison with Plates features I did a blog post.
from foil.
I see. Thanks for your explanation.
While I agree with your points, I have some concerns about the 'On Plates data access' section.
Having worked countless hours with native php templates, I made the following observations:
- variables in the templates are meant to be there, i.e. I had very few situations where I would use a variable that is not set and echo empty string instead. Most of the cases (well.. my cases) all of the variables are set through the controller (on traditional MVC architecture). I barely used isset control structures like your example above.
- actually getting notices for undefined variables is sometimes useful. Especially in development mode, where you could just forget to assign a variable to the template or miswrite its name. Foil could benefit from a 'strict_variables' option, like Twig.
About autoescaping - I guess there is no difference for the end user between escaping a variable on demand, when accessing it from the template with $this->my_var, and escaping all of the variables that are passed to the render function, thus providing escaped scoped vars to the template. Do you see room for an option like 'use_scoped_variables', that would allow to access the template variables without 'this' ?
from foil.
variables in the templates are meant to be there
I've worked countless hours with templates engines, not native php one, but in this regard there is no difference between native or compiled, and I encountered a lot of occasions where variables may be there or not, expecially when data comes from external sources, like API, file parsing...
Moreover, if you know that undefined variables equals empty string, you can use undefined variable by design.
Let's assume that by design a page may has or may not a subtitle. Page template in Plates will probably contain:
<?= isset($subtile) ? $subtile : '' ?>
or a more verbose if
statement. In Foil you just <?= $this->subtile ?>
obtaining same effect.
An alternative would be always assign subtile var to page, but in that case the control structure is moved from template code to data generation code (controller or whatever), that is sure better, but no need for it is even better IMO.
actually getting notices for undefined variables is sometimes useful
I'm pretty agree that 'strict_variables' would by a nice addition I'm going to add myself an issue for it.
I guess there is no difference for the end user between escaping a variable on demand...
Plates documentation itself encourages people to do $this->e('var_name')
.
You can do exactly the same in Foil, but you can also to $this->var_name
(so less typing) when autoescape is turned on.
If we agree that unescaped output is bad (and I agree) Foil gives an easier access to escaped data while unescaped data must be accessed intentionally with $this->raw()
. Plates does the countrary: unescaped data is easily accessed, while escaped data must be required. I feel this is bad and I can say recently even the Laravel Blade do the same thing moving from unescaped-by-default to escaped-by-default.
Do you see room for an option like 'use_scoped_variables'
Yes, I do. Generally speacking I write open source code for things that I like to have but I can't find. This means the default behavior of my code reflects my preferences. But I don't see reason why I have to force people on my preferences.
I have to say that option will destroy the autoescape thing. So I can allow it only if autoescape is off (there is already an option for that).
If you want to add this feature and do a PR it will be merged. If you have no time for that, add a specific issue, I'll handle it when I can. (for the name I feel we can make it less verbose as 'scoped_variables'
).
from foil.
Thanks for the detailed explanation.
My experience with templates is 95% connected with html markup, that's why in my cases $subtitle would be wrapped by span (div, paragraph etc.) and I would use conditional structure to omit this markup regardless of how I access $subtitle. I see this is not valid for the cases you mention (API, file parsing), so I am biased here.
Another attempt to explain my view about autoescaping.
$engine->render('a-template', $template_variables_array);
Why can't the template engine just escape and then extract $template_variables_array before including the template file, so all of the $template_variables_array items would appear as escaped scoped variables in the template ? The original unescaped $template_variables_array can be kept in order to be able to access the raw variables with $this->raw('my_var');. Does this makes sense or I miss the point ?
I didn't mean to question your purposes for creating Foil, just discussing my views on the topic. I will think about a PR.
from foil.
Why can't the template engine just escape and then extract $template_variables_array before including the template file, so all of the $template_variables_array items would appear as escaped scoped variables in the template
This is the biggest issue with autoescape in native PHP templates.
Variables passed to templates are not always strings. Strings can be easily escaped. Array can as well, by recursively parse them.
Problem are objects. While you can get object properties using get_object_vars()
this fails if object implement __get()
overloading method.
Example:
class Post {
private $data;
public function __construct(array $data) {
$this->data = $data;
}
public function __get($var) {
return isset($this->data[$var]) ? $this->data[$var] : '';
}
}
$post = new Post(array('foo' => 'Bar'));
echo $post['foo']; // echo 'Bar'
If the $post
object is passed to templates, there is no way to autoescape post properties.
This problem does not exists for compiled template engines, because they first echo the value (in a sandboxed environment), then escape the echoed value.
The point of arraize
Foil method is to convert all objects to array, so they don't suffer of this issue and can be easily autoescaped.
If the scoped_variable
option is added to Foil, maybe, besides true
/ false
values for it is possible to add support for "arraize"
value: when used, if autoescape is true Foil passes template variable to arraize()
before extract them...
from foil.
Related Issues (20)
- SectionInterface::MODE_REPLACE causes child template inheritance to fail HOT 4
- `supply()` template method does not work when same engine instance is used to render more templates HOT 8
- Nested Blocks Fail HOT 4
- 0.6.4 is now repeating content sections within a loop HOT 8
- Some issues when creating custom helpers HOT 1
- Engine option to echo rendered output HOT 6
- Retrieve Data Inside Templates: loops HOT 14
- Code in overwritten sections runs HOT 2
- Option to not arraize some data HOT 1
- Arraization(?) is turning my Eloquent collections into strings (not arrays) HOT 1
- Trimming output? HOT 5
- New line in doRender of Engine class HOT 3
- Markdown Block HOT 2
- Duplicate code with nested sections HOT 3
- Link to blog post has no content HOT 2
- is not a valid template name HOT 1
- Development roadmap HOT 1
- Documentation website not working HOT 3
- Multiple section replace don't work HOT 2
- Post calls not working on PHP 7.1 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from foil.