Hi, Jonathan
I was considering two approaches : template compilation with static
inheritance and template compilation with static and dynamic
inheritance.
The first one approach has simple way of compilation :
1.Reading template in string
2.Tokenizing
3.Parsing — creating NodeList structure
4.Recuirsive NodeList tree compiling. Note: parent templatea already
in this tree. And my task is to repeat this structure in python
bytecode.
E.g. Template ('TextNodePart\n{% block some_block %}BlockNode
'some_block'{% if True %}IfNode{% endif %}{%endblock%}') :

from ... import ...

def render(context):
        print "TextNodePart"
        print "BlockNode 'some_block'"
        if True :
                print "IfNode"

or, e.g. With static inheritance Template('{% extends 'base.html' %}
SomeTextNode{% block some_block %}{% if True %}ifNode{% endif %}{%
endblock%}'), where base.html — Template('{% block some_block %}{%
endblock %}{% block other_block %}TextNode{% endblock %}') will be
looked :

from … import …

def render(context):
        if True :
                print "ifNode"
        print "TextNode"

But template compilation with dynamic inheritance is a bit more
complicated. Real template structure isn't known at compilation time
of template, because it isn't known what template it will be. At
runtime i tried to find template, compile it, or just import already
compiled template. Structure of final template will be known also at
runtime - thats why I'm collecting blocks output sequence - to output
in this sequence.

E.g. :
child.html :
{% extends parent %}
{% block first_block %}
    {% if True %}
        some_info
    {% endif %}
{% endblock %}
{% block second_block %}
{% endblock %}

parent.html :
TextNode
{% block first_block %}
{% endblock %}

In this example child template has 2 block : first_block and
second_block, but parent template has only 1 block : first_block. And
in this situation I have to print only first_block output...

Compiled child template :
from ... import ...

blocks_output = Template_BlockOutput()
blocks_output_sequence = list()

def output():
    for block_name in blocks_output_sequence :
        if blocks_output.has_key(block_name) :
            print blocks_output[block_name]

def render(context,no_output=False):
    blocks_output['first_block'] = '' # entering block tag
    blocks_sequence_output.append('first_block')
    if True :
        blocks_output['first_block'] = blocks_output['first_block'] +
"some_info"
    blocks_output['second_block'] = ''  # entering block tag

    extenal_blocks_output, external_blocks_sequence_output =
get_compiled_template_or_create(context.parent,no_output=True)
    blocks_output.append(external_blocks_output)
    blocks_sequence_output = external_blocks_sequence_output

    """ function footer """
    if no_output :
        return blocks_output, blocks_output_sequence
    else :
        output()

Compiled parent template :
from ... import ...

blocks_output = Template_BlockOutput()
blocks_output_sequence = list()

def output():
    for block_name in blocks_output_sequence :
        if blocks_output.has_key(block_name) :
            print blocks_output[block_name]

def render(context,no_output=False):
    blocks_output['first_block'] = '' # entering block tag
    blocks_sequence_output.append('first_block')
    """ function footer """
    if no_output :
        return blocks_output, blocks_output_sequence
    else :
        output()


This is draft version of compilation, it has number of defects. I'm
solving them now.

On Apr 1, 12:50 am, Jonathan Slenders <[email protected]>
wrote:
> Another one:
>
> Instead of:
>     def has_key(self,key):
>         for level in xrange(0,len(self._levels)) :
>             if self._levels[level].has_key(key) :
>                 return True
>         return False
>
> do:
>     def has_key(self,key):
>         return any((key in l) for l in self._levels)
>
> Ony one "self" reference, and any-through-iterator is very fast, as
> it's native python code (probably implemented in C). And lazy
> evaluating.
>
> It's challenging to understand your code. Maybe it's easier if you
> explain in words-only how you want to implement inheritance.
>
> -------------------------
>
> My approach would be like this
>
> For a template called 'x', create a dictionary 'x' with maps the block
> names for this template to a func with it's matching implementation
> code.
> Somehow, a method render_block(name) should be made available. So when
> a blocks are nested, one block should be able to call
> render_block(other_name). The render_block method should do a lookup
> in the dictionary for a block with this name, and call it.
>
> Dynamic inheritance can easily be realized by replacing key/value
> pairs in this dict by other implementations. Pass the original
> implementation to the new implementation as an additional function
> parameter. (As a curry.)
>
> I guess it's fast, and can be cached in memory. For each rendering,
> only a copy of the required template dictionaries have to be made.
> (Not even a deep copy.)
>
> -----------------------
>
> Cheers,
> Jonathan

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to