Code Monkey home page Code Monkey logo

Comments (5)

gmazzap avatar gmazzap commented on July 23, 2024

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.

skyosev avatar skyosev commented on July 23, 2024

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.

gmazzap avatar gmazzap commented on July 23, 2024

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.

skyosev avatar skyosev commented on July 23, 2024

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.

gmazzap avatar gmazzap commented on July 23, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.