Re: Add a generic "getter" filter to the built-in library

2013-11-04 Thread Ivan Kharlamov
On 11/04/2013 04:24 AM, Russell Keith-Magee wrote:
> 
> On Sun, Nov 3, 2013 at 9:57 PM, Emanuele Bertoldi
> > wrote:
> 
> I've opened a ticket (#21370) with a proposal for the *inclusion of
> a generic "getter" filter* in the built-in library.
> 
> *Why?*
> 
> Well, because at the moment Django's template system really lacks of
> support for retrieving data from existing context variables in all
> the cases in which the name of the attribute we need is determined
> at execution time.
> 
> 
> It's worth pointing out that this is something the Django core team has
> historically rejected, on the basis that it's a slippery slope from here
> to turning Django's template language into a fully featured programming
> language. So -- fair warning -- the default answer here is going to be
> "No"; it's going to take some convincing to flip that position.
> 
> However, I will admit that this is a use case for which I have some
> sympathy. Cross-cutting arrays of data is one of those things that is a
> lot more complex to do in the context than it would be to do using a
> simple lookup in a template. 
> 
> Formally, I'm probably +0.1 :-)
>  
> 
> *Syntax:*
> 
> {{ object|get:attr_name }}
> 
> Of course the idea is to add a multi-purpose filter which covers
> different use cases (model instances, arbitrary objects, dicts,
> lists, tuples, etc.)
> 
> 
> *IF* we are to add this, I'd be inclined to do this as a primitive of
> the template language itself, rather than as a template filter. This is
> a fundamental concept in context lookup, not a data transformation
> (which is what filters generally represent). 
> 
> The minimal syntactic solution would be to use the colon operator to
> denote arguments in the same way as it does for filters:
> 
>  {{ object:attr_name }}
> 
> or, by introducing square brackets as parseable symbols in the template
> language:
> 
>  {{ object[attr_name] }}
> 
> The latter has the benefit of being compatible with Jinja syntax; the
> downside is that Django templates starts to look even more like a
> programming language.
> 
> Yours, 
> Russ Magee %-)

Hi! I know this is probably wontfix, but I'll bite the bullet and say
that this has less to do with implementing a Turing-complete template
language (which is obviously an issue in a need of urgent attention :-))
and much more to do with template reusability. :-)

Let's say you are working on a system in which users can be assigned
different roles, and, depending on a given role and on the context,  the
user is able to view dynamic number of model fields and attributes.

The most clean and DRY way to work with templates in this situation (as
I see it) is to use a solution similar to the one proposed by the parent
poster.

I'm not even talking about a situation (which you'll obviously consider
much more esoteric) when you have truly dynamic Django models (the ones
that have fields defined by the users during runtime).
`get_FIELD_display` anyone?

I'm not going to say that this is a very big deal, of course, since a
custom template filter is easy to write.

Philosophically speaking, by insisting that this issue should be solved
outside of templates and inside of views, you are putting something that
doesn't belong there, since the parent ticket is about representation
and not about application logic.

Whether his proposal is sufficiently general-purpose to be included in
Django, is another question. I think it is general-purpose.

Best regards,
Ivan

> -- 
> You received this message because you are subscribed to the Google
> Groups "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAJxq84_QtcWsop_hPYorOdYUnWxJVVe39E%2Bxu%3DAyUtd3GpP1HQ%40mail.gmail.com.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5277DA5D.80409%40gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-04 Thread Aymeric Augustin
2013/11/4 Jonathan Slenders 

> there's probably a reason


History.

The drawbacks of deprecating it at this point are large compared to the
benefits.

-- 
Aymeric.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CANE-7mVPkDfRLnbLbhr3y1sDAsYn0M9o-MWspnALTLZ-%3D4FR_g%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-04 Thread Jonathan Slenders
Le lundi 4 novembre 2013 14:13:44 UTC+1, Emanuele Bertoldi a écrit :

> What about the *add* filter? ;) 
>

I forgot about that one.

However, there's probably a reason. It's hard to fix the templating engine 
and implement a "+" operator. Because people would expect that whitespace 
around the "+" should be possible. But that destroys almost all the 
template tags now, because we first do token.split_contents in practically 
every template tag, end then do var.resolve() on every part. Actually, 
var.resolve() should receive the whole string. I think it should even 
evaluate the "==" operator, what is done in the {% if %} tag now. (and the 
length_is filter)

It's of course possible to add a "+" operator and allow all the built-in 
tags to use it in var.resolve(), but it will take forever until all 
external template tags have been fixed. People will expect the "+" to work 
in any context.

I had a backwards-compatible patch to make writing template tags easier and 
more consistent. I'd like to work toward such a consistent context free 
grammar. The patches are from half a year ago, so not sure whether it 
merges, but reviews are welcome.
https://code.djangoproject.com/ticket/20434


b.t.w, if we implement the []-operator, we can maybe use that for slicing 
as well, instead of the slice filter that we have right now.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/47ed653f-9dbd-46c2-8d44-74c3fef4ac09%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-04 Thread Emanuele Bertoldi
Russell Keith-Magee wrote:

> It's worth pointing out that this is something the Django core team has 
> historically rejected, on the basis that it's a slippery slope from here to 
> turning Django's template language into a fully featured programming 
> language. So -- fair warning -- the default answer here is going to be 
> "No"; it's going to take some convincing to flip that position.
>
> However, I will admit that this is a use case for which I have some 
> sympathy. Cross-cutting arrays of data is one of those things that is a lot 
> more complex to do in the context than it would be to do using a simple 
> lookup in a template. 
>
> Formally, I'm probably +0.1 :-)
>

Well, I understand the point but I don't honestly could think to attribute 
lookup as an exclusive feature of "programming languages". 

At the end we're talking about "getting" information, not "setting": if you 
want to show them, you need to retrieve them from somewhere. That's my 
humble opinion and, maybe, a good general principle to distinguish between 
what should be included in template system and what not (then, of course, 
there're always exceptions).
 

> *IF* we are to add this, I'd be inclined to do this as a primitive of the 
> template language itself, rather than as a template filter. This is a 
> fundamental concept in context lookup, not a data transformation (which is 
> what filters generally represent). 
>
> The minimal syntactic solution would be to use the colon operator to 
> denote arguments in the same way as it does for filters:
>
>  {{ object:attr_name }}
>
> or, by introducing square brackets as parseable symbols in the template 
> language:
>
>  {{ object[attr_name] }}
>
> The latter has the benefit of being compatible with Jinja syntax; the 
> downside is that Django templates starts to look even more like a 
> programming language.
>

That would be awesome. 

Jonathan Slenders wrote:

> - The only operators that we should implement are those necessary for data 
> lookups. We shouldn't implement addition or subtraction operators for 
> example.
>

What about the *add* filter? ;) 

Again, we have to remember that in programming there are always exceptions. 
Be too strict to just a theoretical principle could really miss the contact 
with the reality. Frankly speaking, I understand that we don't need another 
programming language for templates but the "with" statement and the already 
cited "add" filter are examples of exceptions at the rule to make the 
template system something realistically useful (do I have to mention all 
the CSS frameworks, sessions/cookies and the new features of HTML5 on 
storage-side as references to the historical failing of too-strict 
markup-only ideas in real world?)

Cheers,
Emanuele

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/c7d3dfea-7e83-4922-af21-f1b065aa4845%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-04 Thread Jonathan Slenders

Rusell's last proposal, using the square brackets sounds the best and 
future proof to me. I think it should be something different from the 
calling syntax of template tags, because calling of an object or retrieving 
a property is not the same.

While I like it, I don't say we should necessarily allow it, but the square 
brackets allow for nesting. e.g.

{{ object[attribute.name] }}

or even:

{{ object[attributes[something].name] }}


Semantically, the following tree are the same:

{{ object.name }}

{{ object["name"] }}

{% with "name" as var %} {{ object[var] }} {% endwith %}

Another reason for using another syntax for filters and attribute lookups 
is that I think it can be possible in the future to use any arbitrary 
object from the context as a filter.
Say, for instance that from a view, we put a dictionary of filters in the 
context. The following would be possible.

{% my_var|my_filters["escape"]:param %}


As said, we should be careful not to create a complete programming 
language. For me, that means:
- Template tags should never cause side effects. (They should not be able 
to change anything in the database or anywhere else. However, that's hard 
to force!)
- The only operators that we should implement are those necessary for data 
lookups. We shouldn't implement addition or subtraction operators for 
example.
- The template author shouldn't have to care whether the attribute lookup 
happens in a dictionary (through getitem) or in an object (through getattr).
- The template author shouldn't be concerned with how expensive some 
attribute lookups are, for instance when an attribute lookup causes a 
database query. (That's also a hard one, we cannot make all lookups cheap, 
or forbid expensive lookups.)

I think in order to avoid that many projects will create their own template 
filters and template tags as workarounds to syntax limitations, we really 
shouldn't artificially limit the syntax to the most obvious lookups. (I'm 
rather against the idea of custom template tags, but not against filters.)

B.t.w. if anyone has template engine related patches ready, I'm always 
willing to review it.

Cheers,
Jonathan



Le lundi 4 novembre 2013 01:24:45 UTC+1, Russell Keith-Magee a écrit :
>
>
> On Sun, Nov 3, 2013 at 9:57 PM, Emanuele Bertoldi 
>  > wrote:
>
>> I've opened a ticket (#21370) with a proposal for the *inclusion of a 
>> generic "getter" filter* in the built-in library.
>>
>> *Why?*
>>
>> Well, because at the moment Django's template system really lacks of 
>> support for retrieving data from existing context variables in all the 
>> cases in which the name of the attribute we need is determined at execution 
>> time.
>>
>
> It's worth pointing out that this is something the Django core team has 
> historically rejected, on the basis that it's a slippery slope from here to 
> turning Django's template language into a fully featured programming 
> language. So -- fair warning -- the default answer here is going to be 
> "No"; it's going to take some convincing to flip that position.
>
> However, I will admit that this is a use case for which I have some 
> sympathy. Cross-cutting arrays of data is one of those things that is a lot 
> more complex to do in the context than it would be to do using a simple 
> lookup in a template. 
>
> Formally, I'm probably +0.1 :-)
>  
>
>> *Syntax:*
>>
>> {{ object|get:attr_name }}
>>
>> Of course the idea is to add a multi-purpose filter which covers 
>> different use cases (model instances, arbitrary objects, dicts, lists, 
>> tuples, etc.)
>>
>
> *IF* we are to add this, I'd be inclined to do this as a primitive of the 
> template language itself, rather than as a template filter. This is a 
> fundamental concept in context lookup, not a data transformation (which is 
> what filters generally represent). 
>
> The minimal syntactic solution would be to use the colon operator to 
> denote arguments in the same way as it does for filters:
>
>  {{ object:attr_name }}
>
> or, by introducing square brackets as parseable symbols in the template 
> language:
>
>  {{ object[attr_name] }}
>
> The latter has the benefit of being compatible with Jinja syntax; the 
> downside is that Django templates starts to look even more like a 
> programming language.
>
> Yours, 
> Russ Magee %-)
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/7a3368e7-1e89-4433-b390-b0ad7a30ef3c%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-03 Thread Curtis Maloney
Since we're on the topic after some goading from loic I did figure out
a backward-compatible way to add call arguments to the filter expression
syntax.

Essentially, you distinguish between foo|filter:arg  and foo|filter(arg...)
by looking for : or (

The same parsing could let you have dict lookups, etc.

I was going to implement something like this in django-contemplation [my
template-engine-as-gedanken project] by mangling the AST.. thus letting me
keep performance as well as having Python syntax.

I'm happy to have a go at implementing simple dict syntax, if there's a
chance it will be accepted.

--
Curtis


On 4 November 2013 11:24, Russell Keith-Magee wrote:

>
> On Sun, Nov 3, 2013 at 9:57 PM, Emanuele Bertoldi <
> emanuele.berto...@gmail.com> wrote:
>
>> I've opened a ticket (#21370) with a proposal for the *inclusion of a
>> generic "getter" filter* in the built-in library.
>>
>> *Why?*
>>
>> Well, because at the moment Django's template system really lacks of
>> support for retrieving data from existing context variables in all the
>> cases in which the name of the attribute we need is determined at execution
>> time.
>>
>
> It's worth pointing out that this is something the Django core team has
> historically rejected, on the basis that it's a slippery slope from here to
> turning Django's template language into a fully featured programming
> language. So -- fair warning -- the default answer here is going to be
> "No"; it's going to take some convincing to flip that position.
>
> However, I will admit that this is a use case for which I have some
> sympathy. Cross-cutting arrays of data is one of those things that is a lot
> more complex to do in the context than it would be to do using a simple
> lookup in a template.
>
> Formally, I'm probably +0.1 :-)
>
>
>> *Syntax:*
>>
>> {{ object|get:attr_name }}
>>
>> Of course the idea is to add a multi-purpose filter which covers
>> different use cases (model instances, arbitrary objects, dicts, lists,
>> tuples, etc.)
>>
>
> *IF* we are to add this, I'd be inclined to do this as a primitive of the
> template language itself, rather than as a template filter. This is a
> fundamental concept in context lookup, not a data transformation (which is
> what filters generally represent).
>
> The minimal syntactic solution would be to use the colon operator to
> denote arguments in the same way as it does for filters:
>
>  {{ object:attr_name }}
>
> or, by introducing square brackets as parseable symbols in the template
> language:
>
>  {{ object[attr_name] }}
>
> The latter has the benefit of being compatible with Jinja syntax; the
> downside is that Django templates starts to look even more like a
> programming language.
>
> Yours,
> Russ Magee %-)
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAJxq84_QtcWsop_hPYorOdYUnWxJVVe39E%2Bxu%3DAyUtd3GpP1HQ%40mail.gmail.com
> .
>
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAG_XiSCLh_iuYniyz5CJKU1KabQnkhd_nDUx5DveYinBMJSjcA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Add a generic "getter" filter to the built-in library

2013-11-03 Thread Russell Keith-Magee
On Sun, Nov 3, 2013 at 9:57 PM, Emanuele Bertoldi <
emanuele.berto...@gmail.com> wrote:

> I've opened a ticket (#21370) with a proposal for the *inclusion of a
> generic "getter" filter* in the built-in library.
>
> *Why?*
>
> Well, because at the moment Django's template system really lacks of
> support for retrieving data from existing context variables in all the
> cases in which the name of the attribute we need is determined at execution
> time.
>

It's worth pointing out that this is something the Django core team has
historically rejected, on the basis that it's a slippery slope from here to
turning Django's template language into a fully featured programming
language. So -- fair warning -- the default answer here is going to be
"No"; it's going to take some convincing to flip that position.

However, I will admit that this is a use case for which I have some
sympathy. Cross-cutting arrays of data is one of those things that is a lot
more complex to do in the context than it would be to do using a simple
lookup in a template.

Formally, I'm probably +0.1 :-)


> *Syntax:*
>
> {{ object|get:attr_name }}
>
> Of course the idea is to add a multi-purpose filter which covers different
> use cases (model instances, arbitrary objects, dicts, lists, tuples, etc.)
>

*IF* we are to add this, I'd be inclined to do this as a primitive of the
template language itself, rather than as a template filter. This is a
fundamental concept in context lookup, not a data transformation (which is
what filters generally represent).

The minimal syntactic solution would be to use the colon operator to denote
arguments in the same way as it does for filters:

 {{ object:attr_name }}

or, by introducing square brackets as parseable symbols in the template
language:

 {{ object[attr_name] }}

The latter has the benefit of being compatible with Jinja syntax; the
downside is that Django templates starts to look even more like a
programming language.

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAJxq84_QtcWsop_hPYorOdYUnWxJVVe39E%2Bxu%3DAyUtd3GpP1HQ%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


Add a generic "getter" filter to the built-in library

2013-11-03 Thread Emanuele Bertoldi
I've opened a ticket (#21370) with a proposal for the *inclusion of a 
generic "getter" filter* in the built-in library.

*Why?*

Well, because at the moment Django's template system really lacks of 
support for retrieving data from existing context variables in all the 
cases in which the name of the attribute we need is determined at execution 
time.

*Syntax:*

{{ object|get:attr_name }}

Of course the idea is to add a multi-purpose filter which covers different 
use cases (model instances, arbitrary objects, dicts, lists, tuples, etc.)

*Some examples of its use:*
*
*
*Access to model data based on a dynamic list of fields*


{% for obj in object_list %}

{% for f in field_list %}
{{ obj|get:f }}
{% endfor %}

{% endfor %}


*Access to dict values based on a dynamic list of keys*

{% for key in key_list %}
{{ dict|get:key }}
{% endfor %}

*Access to a variable index of a list*

{{ list|get:var_index }}


*Ticket link:*

https://code.djangoproject.com/ticket/21370

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/619709ac-6536-4222-8052-a0a6ba9ccdcc%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.