librelist archives

« back to archive

HTML Builder Flask Extension

HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-02 @ 17:39
Hello,

I am working on a HTML builder type Flask extension, similar to the
HTML builder in Werkzeug, but with more features, which target full
HTML document generation. It has support for HTML comments, doctype
definition, and both escaped/unescaped HTML text, etc. It takes
advantage of the Werkzeug endpoint system and defines template
inheritance mechanisms using decorators around it. I targeted
real-world HTML document generation with that.

The source is still in a private repository, since I need to clean
that up as much as possible and make sure test coverage is full, but I
wrote a short use case application in which I included detailed
description:
https://gist.github.com/f5de9c33341400cc01b6

I will make the repository public in the following days.

I will be glad if I receive some feedback about it. Any comments?

Regards,
Zahari

Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-07 @ 23:32
Hey guys,

I just committed my Flask-HTMLBuilder extension:
source: http://github.com/majorz/flask-htmlbuilder
documentation: http://majorz.github.com/flask-htmlbuilder/

I used the Flask extension generator for initial skeleton creation.
Documentation is using flask_small theme. I tried to follow closely
the recommendations and looked how other extensions were done. I would
to ask for an initial review process.

Thanks,
Zahari

On Tue, Nov 2, 2010 at 7:39 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> Hello,
>
> I am working on a HTML builder type Flask extension, similar to the
> HTML builder in Werkzeug, but with more features, which target full
> HTML document generation. It has support for HTML comments, doctype
> definition, and both escaped/unescaped HTML text, etc. It takes
> advantage of the Werkzeug endpoint system and defines template
> inheritance mechanisms using decorators around it. I targeted
> real-world HTML document generation with that.
>
> The source is still in a private repository, since I need to clean
> that up as much as possible and make sure test coverage is full, but I
> wrote a short use case application in which I included detailed
> description:
> https://gist.github.com/f5de9c33341400cc01b6
>
> I will make the repository public in the following days.
>
> I will be glad if I receive some feedback about it. Any comments?
>
> Regards,
> Zahari
>

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-08 @ 11:30
On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
> Hey guys,
> 
> I just committed my Flask-HTMLBuilder extension:
> source: http://github.com/majorz/flask-htmlbuilder
> documentation: http://majorz.github.com/flask-htmlbuilder/
> 
> I used the Flask extension generator for initial skeleton creation.
> Documentation is using flask_small theme. I tried to follow closely
> the recommendations and looked how other extensions were done. I would
> to ask for an initial review process.
> 
> Thanks,
> Zahari
> 
> On Tue, Nov 2, 2010 at 7:39 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> > Hello,
> >
> > I am working on a HTML builder type Flask extension, similar to the
> > HTML builder in Werkzeug, but with more features, which target full
> > HTML document generation. It has support for HTML comments, doctype
> > definition, and both escaped/unescaped HTML text, etc. It takes
> > advantage of the Werkzeug endpoint system and defines template
> > inheritance mechanisms using decorators around it. I targeted
> > real-world HTML document generation with that.
> >
> > The source is still in a private repository, since I need to clean
> > that up as much as possible and make sure test coverage is full, but I
> > wrote a short use case application in which I included detailed
> > description:
> > https://gist.github.com/f5de9c33341400cc01b6
> >
> > I will make the repository public in the following days.
> >
> > I will be glad if I receive some feedback about it. Any comments?
> >
> > Regards,
> > Zahari
> >

Some quick thoughts:

- html.doctype() could take a format, type and version and generate a
corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
useful defaults.

- Markup() from Jinja and Genshi should work as substitutes for
html.safe() if they don't already. Some Flask extensions rely on this.

- I still think you should use genshi.builder. You'd get a lot for free,
including doctypes. It's not possible to output valid HTML 4 with your
implementation. I can help you with how to use Genshi.

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-08 @ 12:17
Thanks Dag, my comments are inlined.

On Mon, Nov 8, 2010 at 1:30 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
>> Hey guys,
>>
>> I just committed my Flask-HTMLBuilder extension:
>> source: http://github.com/majorz/flask-htmlbuilder
>> documentation: http://majorz.github.com/flask-htmlbuilder/
>>
>> I used the Flask extension generator for initial skeleton creation.
>> Documentation is using flask_small theme. I tried to follow closely
>> the recommendations and looked how other extensions were done. I would
>> to ask for an initial review process.
>>
>> Thanks,
>> Zahari
>>
>
> Some quick thoughts:
>
> - html.doctype() could take a format, type and version and generate a
> corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
> useful defaults.

That sounds a nice idea. I actually left thinking about compatibility
with HTML4 for a later time, since I wanted to make sure HTML5 is
covered well. But I will definitely do it, unless something convinces
me that HTML5 support is far from enough. Basically HTML4 support in
my library is needed only if someone wants to use my extension as
snippets in existing HTML4 markup. Otherwise there is no reason he
should not go with HTML5, since it is backwards compatible with HTML4
and cleaner. XHTML2 is officially dead now, and people from both
working groups are working on HTML5. I particularly like that comic:

http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/

> - Markup() from Jinja and Genshi should work as substitutes for
> html.safe() if they don't already. Some Flask extensions rely on this.

I will look at Markup of Jinja and Genshi, to see whether I am missing
something. html.safe is quite a simple operation in my extension -
just returning a string as is without escaping it.

> - I still think you should use genshi.builder. You'd get a lot for free,
> including doctypes. It's not possible to output valid HTML 4 with your
> implementation. I can help you with how to use Genshi.

Yes, I will add support for closing void elements with and without
slashes. Since HTML5 supports them both (and IMO xhtml way is
cleaner), I thought for now it will suffice just the xhtml way. It is
a matter of a few additional lines in the code.

I am still not convinced that I should use Genshi, because I do not
see why, but I guess I may miss something. Can you try to elaborate
more on that, please?

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-08 @ 13:38
On Mon, 2010-11-08 at 14:17 +0200, Zahari Petkov wrote:
> Thanks Dag, my comments are inlined.
> 
> On Mon, Nov 8, 2010 at 1:30 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> > On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
> >> Hey guys,
> >>
> >> I just committed my Flask-HTMLBuilder extension:
> >> source: http://github.com/majorz/flask-htmlbuilder
> >> documentation: http://majorz.github.com/flask-htmlbuilder/
> >>
> >> I used the Flask extension generator for initial skeleton creation.
> >> Documentation is using flask_small theme. I tried to follow closely
> >> the recommendations and looked how other extensions were done. I would
> >> to ask for an initial review process.
> >>
> >> Thanks,
> >> Zahari
> >>
> >
> > Some quick thoughts:
> >
> > - html.doctype() could take a format, type and version and generate a
> > corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
> > useful defaults.
> 
> That sounds a nice idea. I actually left thinking about compatibility
> with HTML4 for a later time, since I wanted to make sure HTML5 is
> covered well. But I will definitely do it, unless something convinces
> me that HTML5 support is far from enough. Basically HTML4 support in
> my library is needed only if someone wants to use my extension as
> snippets in existing HTML4 markup. Otherwise there is no reason he
> should not go with HTML5, since it is backwards compatible with HTML4
> and cleaner. XHTML2 is officially dead now, and people from both
> working groups are working on HTML5. I particularly like that comic:
> 
http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/

http://www.infoworld.com/d/developer-world/w3c-hold-html5-in-websites-041

http://webkit.org/blog/68/understanding-html-xml-and-xhtml/

<tag /> is invalid HTML 4, and many browsers parse HTML 5 as HTML 4. No
major browser actually supports XHTML. <tag /> isn't even sensible XML.
<script src/> can screw up some engines a lot, does your implementation
handle that situation? Genshi does all that for you, you can output HTML
4-ish, XHTML-ish or pure XML-ish, on the fly. HTML 5 is only backwards
compatible if used as HTML 4, and you're using it as XHTML.

> 
> > - Markup() from Jinja and Genshi should work as substitutes for
> > html.safe() if they don't already. Some Flask extensions rely on this.
> 
> I will look at Markup of Jinja and Genshi, to see whether I am missing
> something. html.safe is quite a simple operation in my extension -
> just returning a string as is without escaping it.

Then it should work, but possibly you want to escape strings passed as
content to a tag, unless it hasattr '__html__' and in that case use
that. That might be safer, and should work with Markup(). Did I mention
that Genshi's builder does this exactly already? :)

> 
> > - I still think you should use genshi.builder. You'd get a lot for free,
> > including doctypes. It's not possible to output valid HTML 4 with your
> > implementation. I can help you with how to use Genshi.
> 
> Yes, I will add support for closing void elements with and without
> slashes. Since HTML5 supports them both (and IMO xhtml way is
> cleaner), I thought for now it will suffice just the xhtml way. It is
> a matter of a few additional lines in the code.

Not that few, you'd have to keep track of which tags are content tags or
not in HTML. Not that big a deal of course, but, hey guess what: Genshi
does this exactly already.

> 
> I am still not convinced that I should use Genshi, because I do not
> see why, but I guess I may miss something. Can you try to elaborate
> more on that, please?

Why *not*? You seem to have a case of the NIH. You're complicating what
should be a simple extension (Flask extensions should usually be thin
wrappers around existing libraries), bloating your source, reinventing
the wheel and ending up with a less powerful tool.

Is it dependency fear, feeling Genshi does more than you need so it's a
heavy dependency? Have you considered that Flask depends on Werkzeug, of
which you don't use everything, and Jinja, which you don't use at all
with your extension? Don't fear dependencies.

BTW I think the Genshi builder has the exact same API as your builder,
building-wise. Anything you don't like you can just hide in your
extension.

> 
> Thanks,
> Zahari


Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-08 @ 15:58
On Mon, Nov 8, 2010 at 3:38 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Mon, 2010-11-08 at 14:17 +0200, Zahari Petkov wrote:
>> Thanks Dag, my comments are inlined.
>>
>> On Mon, Nov 8, 2010 at 1:30 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> > On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
>> >> Hey guys,
>> >>
>> >> I just committed my Flask-HTMLBuilder extension:
>> >> source: http://github.com/majorz/flask-htmlbuilder
>> >> documentation: http://majorz.github.com/flask-htmlbuilder/
>> >>
>> >> I used the Flask extension generator for initial skeleton creation.
>> >> Documentation is using flask_small theme. I tried to follow closely
>> >> the recommendations and looked how other extensions were done. I would
>> >> to ask for an initial review process.
>> >>
>> >> Thanks,
>> >> Zahari
>> >>
>> >
>> > Some quick thoughts:
>> >
>> > - html.doctype() could take a format, type and version and generate a
>> > corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
>> > useful defaults.
>>
>> That sounds a nice idea. I actually left thinking about compatibility
>> with HTML4 for a later time, since I wanted to make sure HTML5 is
>> covered well. But I will definitely do it, unless something convinces
>> me that HTML5 support is far from enough. Basically HTML4 support in
>> my library is needed only if someone wants to use my extension as
>> snippets in existing HTML4 markup. Otherwise there is no reason he
>> should not go with HTML5, since it is backwards compatible with HTML4
>> and cleaner. XHTML2 is officially dead now, and people from both
>> working groups are working on HTML5. I particularly like that comic:
>> 
http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/
>
> http://www.infoworld.com/d/developer-world/w3c-hold-html5-in-websites-041
>

That article is about the newest features in HTML5, not about the
backwards compatibility, so I think it is misleading. Furthermore,
taking into account that projects like Modernizr exist and prove to be
working well across older browsers like IE6, a developer may use
feature detection capabilities to decides on newer HTML5 features.
BTW, the most used website in the world (google.com) is serving HTML5.

> http://webkit.org/blog/68/understanding-html-xml-and-xhtml/
>
> <tag /> is invalid HTML 4, and many browsers parse HTML 5 as HTML 4. No
> major browser actually supports XHTML. <tag /> isn't even sensible XML.
> <script src/> can screw up some engines a lot, does your implementation
> handle that situation? Genshi does all that for you, you can output HTML
> 4-ish, XHTML-ish or pure XML-ish, on the fly. HTML 5 is only backwards
> compatible if used as HTML 4, and you're using it as XHTML.
>

As I said I will allow users to choose between both ways of closing
void elements, I just need to figure out an elegant way of doing it. I
do not intend to put validation capabilities to my extension for now.
Let's take your script example actually:
HTML: <script src="/js/mighty.js" />  Python:
html.script(src='/js/mighty.js') - Bad
HTML: <script src="/js/mighty.js"></script>  Python:
html.script(src='/js/mighty.js')() - Problem solved, yeah?

Jeffrey Zeldman uses HTML5 with XHTML dialect for closing void
elements. His website works nice in IE6. I think that clarifies pretty
well that my approach is backwards compatible as well.

>>
>> > - Markup() from Jinja and Genshi should work as substitutes for
>> > html.safe() if they don't already. Some Flask extensions rely on this.
>>
>> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> something. html.safe is quite a simple operation in my extension -
>> just returning a string as is without escaping it.
>
> Then it should work, but possibly you want to escape strings passed as
> content to a tag, unless it hasattr '__html__' and in that case use
> that. That might be safer, and should work with Markup(). Did I mention
> that Genshi's builder does this exactly already? :)

Thanks. Armin clarified that I should work on that to get approval and
will do it.

>
>>
>> > - I still think you should use genshi.builder. You'd get a lot for free,
>> > including doctypes. It's not possible to output valid HTML 4 with your
>> > implementation. I can help you with how to use Genshi.
>>
>> Yes, I will add support for closing void elements with and without
>> slashes. Since HTML5 supports them both (and IMO xhtml way is
>> cleaner), I thought for now it will suffice just the xhtml way. It is
>> a matter of a few additional lines in the code.
>
> Not that few, you'd have to keep track of which tags are content tags or
> not in HTML. Not that big a deal of course, but, hey guess what: Genshi
> does this exactly already.
>

Why should I do that? I prefer to leave those to the user and not
provide validation as I talked above.

>>
>> I am still not convinced that I should use Genshi, because I do not
>> see why, but I guess I may miss something. Can you try to elaborate
>> more on that, please?
>
> Why *not*? You seem to have a case of the NIH. You're complicating what
> should be a simple extension (Flask extensions should usually be thin
> wrappers around existing libraries), bloating your source, reinventing
> the wheel and ending up with a less powerful tool.
>

My source is definitely not bloated, nor is less powerful. We may say
that it is still work in progress though - that's why my version there
is 0.3 (the previous two were internal non-flask related).

While Flask extensions normally are just wrappers (I agree), that does
not invalidate the opposite approach in any way.

> Is it dependency fear, feeling Genshi does more than you need so it's a
> heavy dependency? Have you considered that Flask depends on Werkzeug, of
> which you don't use everything, and Jinja, which you don't use at all
> with your extension? Don't fear dependencies.
>
> BTW I think the Genshi builder has the exact same API as your builder,
> building-wise. Anything you don't like you can just hide in your
> extension.

To tell a joke, IMO, Genshi builder is quite less-powerful. I have
concrete evidence with the standard Big Table template benchmark:
Flask-HTMLBuilder builder                      261.97 ms
Werkzeug HTMLBuilder                          196.30 ms
Genshi tag builder                            831.50 ms
Genshi template                               482.97 ms
Genshi text template                          343.76 ms
Genshi template + tag builder                 912.09 ms
ElementTree                                   350.67 ms
cElementTree                                  198.58 ms
Django template                              1046.46 ms

As we can see it is 3-4 times slower, what so powerful about it...
Okay, more seriously now. My API is different actually though there
are a lot of similarities.

One quick example with what you talked about:
Me:
>>> str(html.script(src='/js/mighty.js')())
'<script src="/js/mighty.js"></script>'
Genshi:
>>> str(tag.script(src='/js/mighty.js')())
'<script src="/js/mighty.js"/>'
>>> str(tag.script(src='/js/mighty.js')(''))
'<script src="/js/mighty.js"></script>'

I do not like how Genshi does not put a space before the closing slash
as well. And there is more to that, but it is useless to continue.

Anyway, my idea is to have a Python-only solution. Genshi's main
purpose is different, though it provides the builder module. I do not
like mixing those concepts by introducing such dependency.

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-08 @ 23:45
On Mon, 2010-11-08 at 17:58 +0200, Zahari Petkov wrote:
> On Mon, Nov 8, 2010 at 3:38 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> > On Mon, 2010-11-08 at 14:17 +0200, Zahari Petkov wrote:
> >> Thanks Dag, my comments are inlined.
> >>
> >> On Mon, Nov 8, 2010 at 1:30 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> >> > On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
> >> >> Hey guys,
> >> >>
> >> >> I just committed my Flask-HTMLBuilder extension:
> >> >> source: http://github.com/majorz/flask-htmlbuilder
> >> >> documentation: http://majorz.github.com/flask-htmlbuilder/
> >> >>
> >> >> I used the Flask extension generator for initial skeleton creation.
> >> >> Documentation is using flask_small theme. I tried to follow closely
> >> >> the recommendations and looked how other extensions were done. I would
> >> >> to ask for an initial review process.
> >> >>
> >> >> Thanks,
> >> >> Zahari
> >> >>
> >> >
> >> > Some quick thoughts:
> >> >
> >> > - html.doctype() could take a format, type and version and generate a
> >> > corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
> >> > useful defaults.
> >>
> >> That sounds a nice idea. I actually left thinking about compatibility
> >> with HTML4 for a later time, since I wanted to make sure HTML5 is
> >> covered well. But I will definitely do it, unless something convinces
> >> me that HTML5 support is far from enough. Basically HTML4 support in
> >> my library is needed only if someone wants to use my extension as
> >> snippets in existing HTML4 markup. Otherwise there is no reason he
> >> should not go with HTML5, since it is backwards compatible with HTML4
> >> and cleaner. XHTML2 is officially dead now, and people from both
> >> working groups are working on HTML5. I particularly like that comic:
> >> 
http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/
> >
> > http://www.infoworld.com/d/developer-world/w3c-hold-html5-in-websites-041
> >
> 
> That article is about the newest features in HTML5, not about the
> backwards compatibility, so I think it is misleading. Furthermore,
> taking into account that projects like Modernizr exist and prove to be
> working well across older browsers like IE6, a developer may use
> feature detection capabilities to decides on newer HTML5 features.
> BTW, the most used website in the world (google.com) is serving HTML5.

Just a note: I'm all for HTML 5, but supporting HTML 4 is still
important today.

> 
> > http://webkit.org/blog/68/understanding-html-xml-and-xhtml/
> >
> > <tag /> is invalid HTML 4, and many browsers parse HTML 5 as HTML 4. No
> > major browser actually supports XHTML. <tag /> isn't even sensible XML.
> > <script src/> can screw up some engines a lot, does your implementation
> > handle that situation? Genshi does all that for you, you can output HTML
> > 4-ish, XHTML-ish or pure XML-ish, on the fly. HTML 5 is only backwards
> > compatible if used as HTML 4, and you're using it as XHTML.
> >
> 
> As I said I will allow users to choose between both ways of closing
> void elements, I just need to figure out an elegant way of doing it. I
> do not intend to put validation capabilities to my extension for now.
> Let's take your script example actually:
> HTML: <script src="/js/mighty.js" />  Python:
> html.script(src='/js/mighty.js') - Bad
> HTML: <script src="/js/mighty.js"></script>  Python:
> html.script(src='/js/mighty.js')() - Problem solved, yeah?
> 
> Jeffrey Zeldman uses HTML5 with XHTML dialect for closing void
> elements. His website works nice in IE6. I think that clarifies pretty
> well that my approach is backwards compatible as well.
> 
> >>
> >> > - Markup() from Jinja and Genshi should work as substitutes for
> >> > html.safe() if they don't already. Some Flask extensions rely on this.
> >>
> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
> >> something. html.safe is quite a simple operation in my extension -
> >> just returning a string as is without escaping it.
> >
> > Then it should work, but possibly you want to escape strings passed as
> > content to a tag, unless it hasattr '__html__' and in that case use
> > that. That might be safer, and should work with Markup(). Did I mention
> > that Genshi's builder does this exactly already? :)
> 
> Thanks. Armin clarified that I should work on that to get approval and
> will do it.
> 
> >
> >>
> >> > - I still think you should use genshi.builder. You'd get a lot for free,
> >> > including doctypes. It's not possible to output valid HTML 4 with your
> >> > implementation. I can help you with how to use Genshi.
> >>
> >> Yes, I will add support for closing void elements with and without
> >> slashes. Since HTML5 supports them both (and IMO xhtml way is
> >> cleaner), I thought for now it will suffice just the xhtml way. It is
> >> a matter of a few additional lines in the code.
> >
> > Not that few, you'd have to keep track of which tags are content tags or
> > not in HTML. Not that big a deal of course, but, hey guess what: Genshi
> > does this exactly already.
> >
> 
> Why should I do that? I prefer to leave those to the user and not
> provide validation as I talked above.

Makes sense for an XML builder, less so for rendering output for the web
IMHO.

> 
> >>
> >> I am still not convinced that I should use Genshi, because I do not
> >> see why, but I guess I may miss something. Can you try to elaborate
> >> more on that, please?
> >
> > Why *not*? You seem to have a case of the NIH. You're complicating what
> > should be a simple extension (Flask extensions should usually be thin
> > wrappers around existing libraries), bloating your source, reinventing
> > the wheel and ending up with a less powerful tool.
> >
> 
> My source is definitely not bloated, nor is less powerful. We may say
> that it is still work in progress though - that's why my version there
> is 0.3 (the previous two were internal non-flask related).

Sorry, I didn't mean to say that it was - only compared to a
hypothetical source where the builder is a separate library.

> 
> While Flask extensions normally are just wrappers (I agree), that does
> not invalidate the opposite approach in any way.
> 
> > Is it dependency fear, feeling Genshi does more than you need so it's a
> > heavy dependency? Have you considered that Flask depends on Werkzeug, of
> > which you don't use everything, and Jinja, which you don't use at all
> > with your extension? Don't fear dependencies.
> >
> > BTW I think the Genshi builder has the exact same API as your builder,
> > building-wise. Anything you don't like you can just hide in your
> > extension.
> 
> To tell a joke, IMO, Genshi builder is quite less-powerful. I have
> concrete evidence with the standard Big Table template benchmark:
> Flask-HTMLBuilder builder                      261.97 ms
> Werkzeug HTMLBuilder                          196.30 ms
> Genshi tag builder                            831.50 ms
> Genshi template                               482.97 ms
> Genshi text template                          343.76 ms
> Genshi template + tag builder                 912.09 ms
> ElementTree                                   350.67 ms
> cElementTree                                  198.58 ms
> Django template                              1046.46 ms

Irrelevant for most people. Django is clearly the slowest and yet a
great lot of people use it in production systems. Templating is rarely a
culprit.

> 
> As we can see it is 3-4 times slower, what so powerful about it...
> Okay, more seriously now. My API is different actually though there
> are a lot of similarities.
> 
> One quick example with what you talked about:
> Me:
> >>> str(html.script(src='/js/mighty.js')())
> '<script src="/js/mighty.js"></script>'
> Genshi:
> >>> str(tag.script(src='/js/mighty.js')())
> '<script src="/js/mighty.js"/>'
> >>> str(tag.script(src='/js/mighty.js')(''))
> '<script src="/js/mighty.js"></script>'
> 
> I do not like how Genshi does not put a space before the closing slash
> as well. And there is more to that, but it is useless to continue.

>>> tag.hr().generate().render('html')
'<hr>'
>>> tag.hr().generate().render('xhtml')
'<hr />'


> 
> Anyway, my idea is to have a Python-only solution. Genshi's main
> purpose is different, though it provides the builder module. I do not
> like mixing those concepts by introducing such dependency.

I at least think you should separate the Flask extension and your
builder and make the latter a library in its own right.

(Just wanted to provide a friendly advice with genshi.builder, I hope
I'm not coming off too strong about it. +1 for adding to the set of
Flask extensions.)

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 00:02
On Tue, Nov 9, 2010 at 1:45 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Mon, 2010-11-08 at 17:58 +0200, Zahari Petkov wrote:
>> On Mon, Nov 8, 2010 at 3:38 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> > On Mon, 2010-11-08 at 14:17 +0200, Zahari Petkov wrote:
>> >> Thanks Dag, my comments are inlined.
>> >>
>> >> On Mon, Nov 8, 2010 at 1:30 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> >> > On Mon, 2010-11-08 at 01:32 +0200, Zahari Petkov wrote:
>> >> >> Hey guys,
>> >> >>
>> >> >> I just committed my Flask-HTMLBuilder extension:
>> >> >> source: http://github.com/majorz/flask-htmlbuilder
>> >> >> documentation: http://majorz.github.com/flask-htmlbuilder/
>> >> >>
>> >> >> I used the Flask extension generator for initial skeleton creation.
>> >> >> Documentation is using flask_small theme. I tried to follow closely
>> >> >> the recommendations and looked how other extensions were done. I would
>> >> >> to ask for an initial review process.
>> >> >>
>> >> >> Thanks,
>> >> >> Zahari
>> >> >>
>> >> >
>> >> > Some quick thoughts:
>> >> >
>> >> > - html.doctype() could take a format, type and version and generate a
>> >> > corresponding doctype, i.e. html.doctype('html', 4, 'strict'), with some
>> >> > useful defaults.
>> >>
>> >> That sounds a nice idea. I actually left thinking about compatibility
>> >> with HTML4 for a later time, since I wanted to make sure HTML5 is
>> >> covered well. But I will definitely do it, unless something convinces
>> >> me that HTML5 support is far from enough. Basically HTML4 support in
>> >> my library is needed only if someone wants to use my extension as
>> >> snippets in existing HTML4 markup. Otherwise there is no reason he
>> >> should not go with HTML5, since it is backwards compatible with HTML4
>> >> and cleaner. XHTML2 is officially dead now, and people from both
>> >> working groups are working on HTML5. I particularly like that comic:
>> >> 
http://www.smashingmagazine.com/2009/07/29/misunderstanding-markup-xhtml-2-comic-strip/
>> >
>> > http://www.infoworld.com/d/developer-world/w3c-hold-html5-in-websites-041
>> >
>>
>> That article is about the newest features in HTML5, not about the
>> backwards compatibility, so I think it is misleading. Furthermore,
>> taking into account that projects like Modernizr exist and prove to be
>> working well across older browsers like IE6, a developer may use
>> feature detection capabilities to decides on newer HTML5 features.
>> BTW, the most used website in the world (google.com) is serving HTML5.
>
> Just a note: I'm all for HTML 5, but supporting HTML 4 is still
> important today.
>

Well, yeah, I guess I should live with that :D

>>
>> > http://webkit.org/blog/68/understanding-html-xml-and-xhtml/
>> >
>> > <tag /> is invalid HTML 4, and many browsers parse HTML 5 as HTML 4. No
>> > major browser actually supports XHTML. <tag /> isn't even sensible XML.
>> > <script src/> can screw up some engines a lot, does your implementation
>> > handle that situation? Genshi does all that for you, you can output HTML
>> > 4-ish, XHTML-ish or pure XML-ish, on the fly. HTML 5 is only backwards
>> > compatible if used as HTML 4, and you're using it as XHTML.
>> >
>>
>> As I said I will allow users to choose between both ways of closing
>> void elements, I just need to figure out an elegant way of doing it. I
>> do not intend to put validation capabilities to my extension for now.
>> Let's take your script example actually:
>> HTML: <script src="/js/mighty.js" />  Python:
>> html.script(src='/js/mighty.js') - Bad
>> HTML: <script src="/js/mighty.js"></script>  Python:
>> html.script(src='/js/mighty.js')() - Problem solved, yeah?
>>
>> Jeffrey Zeldman uses HTML5 with XHTML dialect for closing void
>> elements. His website works nice in IE6. I think that clarifies pretty
>> well that my approach is backwards compatible as well.
>>
>> >>
>> >> > - Markup() from Jinja and Genshi should work as substitutes for
>> >> > html.safe() if they don't already. Some Flask extensions rely on this.
>> >>
>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> >> something. html.safe is quite a simple operation in my extension -
>> >> just returning a string as is without escaping it.
>> >
>> > Then it should work, but possibly you want to escape strings passed as
>> > content to a tag, unless it hasattr '__html__' and in that case use
>> > that. That might be safer, and should work with Markup(). Did I mention
>> > that Genshi's builder does this exactly already? :)
>>
>> Thanks. Armin clarified that I should work on that to get approval and
>> will do it.
>>
>> >
>> >>
>> >> > - I still think you should use genshi.builder. You'd get a lot for free,
>> >> > including doctypes. It's not possible to output valid HTML 4 with your
>> >> > implementation. I can help you with how to use Genshi.
>> >>
>> >> Yes, I will add support for closing void elements with and without
>> >> slashes. Since HTML5 supports them both (and IMO xhtml way is
>> >> cleaner), I thought for now it will suffice just the xhtml way. It is
>> >> a matter of a few additional lines in the code.
>> >
>> > Not that few, you'd have to keep track of which tags are content tags or
>> > not in HTML. Not that big a deal of course, but, hey guess what: Genshi
>> > does this exactly already.
>> >
>>
>> Why should I do that? I prefer to leave those to the user and not
>> provide validation as I talked above.
>
> Makes sense for an XML builder, less so for rendering output for the web
> IMHO.
>

Ah, okay, I got it now. I will keep in mind that..

>>
>> >>
>> >> I am still not convinced that I should use Genshi, because I do not
>> >> see why, but I guess I may miss something. Can you try to elaborate
>> >> more on that, please?
>> >
>> > Why *not*? You seem to have a case of the NIH. You're complicating what
>> > should be a simple extension (Flask extensions should usually be thin
>> > wrappers around existing libraries), bloating your source, reinventing
>> > the wheel and ending up with a less powerful tool.
>> >
>>
>> My source is definitely not bloated, nor is less powerful. We may say
>> that it is still work in progress though - that's why my version there
>> is 0.3 (the previous two were internal non-flask related).
>
> Sorry, I didn't mean to say that it was - only compared to a
> hypothetical source where the builder is a separate library.
>

Yes, it will be 1/2--2/3 shorter this way and other people from the
Python community will benefit from it.

>>
>> While Flask extensions normally are just wrappers (I agree), that does
>> not invalidate the opposite approach in any way.
>>
>> > Is it dependency fear, feeling Genshi does more than you need so it's a
>> > heavy dependency? Have you considered that Flask depends on Werkzeug, of
>> > which you don't use everything, and Jinja, which you don't use at all
>> > with your extension? Don't fear dependencies.
>> >
>> > BTW I think the Genshi builder has the exact same API as your builder,
>> > building-wise. Anything you don't like you can just hide in your
>> > extension.
>>
>> To tell a joke, IMO, Genshi builder is quite less-powerful. I have
>> concrete evidence with the standard Big Table template benchmark:
>> Flask-HTMLBuilder builder                      261.97 ms
>> Werkzeug HTMLBuilder                          196.30 ms
>> Genshi tag builder                            831.50 ms
>> Genshi template                               482.97 ms
>> Genshi text template                          343.76 ms
>> Genshi template + tag builder                 912.09 ms
>> ElementTree                                   350.67 ms
>> cElementTree                                  198.58 ms
>> Django template                              1046.46 ms
>
> Irrelevant for most people. Django is clearly the slowest and yet a
> great lot of people use it in production systems. Templating is rarely a
> culprit.
>

I have the gut feeling that their performance penalty comes from their
escaping mechanisms, but that is unrelated anyway.

Talking about performance I am planning to do a Cython version of my
extension when I have more time to play with that (at least the part
that should be moved in a standalone package). It will be interesting
to see the results.

>>
>> As we can see it is 3-4 times slower, what so powerful about it...
>> Okay, more seriously now. My API is different actually though there
>> are a lot of similarities.
>>
>> One quick example with what you talked about:
>> Me:
>> >>> str(html.script(src='/js/mighty.js')())
>> '<script src="/js/mighty.js"></script>'
>> Genshi:
>> >>> str(tag.script(src='/js/mighty.js')())
>> '<script src="/js/mighty.js"/>'
>> >>> str(tag.script(src='/js/mighty.js')(''))
>> '<script src="/js/mighty.js"></script>'
>>
>> I do not like how Genshi does not put a space before the closing slash
>> as well. And there is more to that, but it is useless to continue.
>
>>>> tag.hr().generate().render('html')
> '<hr>'
>>>> tag.hr().generate().render('xhtml')
> '<hr />'
>

Well, that is confusing -- whatever :)
>>> str(tag.hr())
'<hr/>'
>>> tag.hr().generate().render('xhtml')
'<hr />'

>
>>
>> Anyway, my idea is to have a Python-only solution. Genshi's main
>> purpose is different, though it provides the builder module. I do not
>> like mixing those concepts by introducing such dependency.
>
> I at least think you should separate the Flask extension and your
> builder and make the latter a library in its own right.
>
> (Just wanted to provide a friendly advice with genshi.builder, I hope
> I'm not coming off too strong about it. +1 for adding to the set of
> Flask extensions.)
>

I understand you, no problem :) Thanks for the ideas and the response,
it's always very appreciated.
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
danjac354@gmail.com
Date:
2010-11-08 @ 16:08
> While Flask extensions normally are just wrappers (I agree), that does
> not invalidate the opposite approach in any way.

Why not have the HTMLBuilder as a separate package (and therefore
useful to the greatest number of Python developers) and write a
Flask-HTMLBuilder extension that can use it ?

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-08 @ 17:31
On Mon, Nov 8, 2010 at 6:08 PM, danjac354@gmail.com <danjac354@gmail.com> wrote:
>> While Flask extensions normally are just wrappers (I agree), that does
>> not invalidate the opposite approach in any way.
>
> Why not have the HTMLBuilder as a separate package (and therefore
> useful to the greatest number of Python developers) and write a
> Flask-HTMLBuilder extension that can use it ?
>

I initially decided to get in this direction, but then decided to stay
with Flask-only implementation. My code is half-dependent on
Flask/Werkzeug, half-independent on them. But the basic HTML builder
part can be isolated in a package of it's own, so I appreciate your
suggestion very much. I may split the project soon so that more people
can benefit from it.

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Armin Ronacher
Date:
2010-11-08 @ 13:02
Hi,

On 2010-11-08 1:17 PM, Zahari Petkov wrote:
> I will look at Markup of Jinja and Genshi, to see whether I am missing
> something. html.safe is quite a simple operation in my extension -
> just returning a string as is without escaping it.
Make sure to support Markup or its impossible for this extension to ever 
get a seal of approval :)


Regards,
Armin

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 01:02
On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
<armin.ronacher@active-4.com> wrote:
> Hi,
>
> On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> something. html.safe is quite a simple operation in my extension -
>> just returning a string as is without escaping it.
> Make sure to support Markup or its impossible for this extension to ever
> get a seal of approval :)
>

I committed Markup support but I am a bit confused about whether my
__html__ method should return just a unicode string or a jinja2 Markup
object? I made it returning a unicode for now. I added some tests as
well.

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-09 @ 07:33
On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
> <armin.ronacher@active-4.com> wrote:
> > Hi,
> >
> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
> >> something. html.safe is quite a simple operation in my extension -
> >> just returning a string as is without escaping it.
> > Make sure to support Markup or its impossible for this extension to ever
> > get a seal of approval :)
> >
> 
> I committed Markup support but I am a bit confused about whether my
> __html__ method should return just a unicode string or a jinja2 Markup
> object? I made it returning a unicode for now. I added some tests as
> well.
> 
> Thanks,
> Zahari

Markup() is pointless unless combined with escaping of markup, automatic
or not. If you have a function for escaping markup, given an object that
implements __html__, that method should be used unescaped. If you have
automatic escaping (and you should) of strings used as content in a tag,
the same logic applies. You don't need to reimplement Markup(), you can
just from flask import Markup.

>>> html.p('<em>Example</em>')
'<p><em>Example</em></p>'
>>> html.p(Markup('<em>Example</em>'))
'<p><em>Example</em></p>'

Flask's Markup() is just a subclass of unicode, adding __html__.

If for some reason you want a html.safe() even though that's just a
longer version of Markup() :) you just make it return Markup().

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 07:54
On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>> <armin.ronacher@active-4.com> wrote:
>> > Hi,
>> >
>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> >> something. html.safe is quite a simple operation in my extension -
>> >> just returning a string as is without escaping it.
>> > Make sure to support Markup or its impossible for this extension to ever
>> > get a seal of approval :)
>> >
>>
>> I committed Markup support but I am a bit confused about whether my
>> __html__ method should return just a unicode string or a jinja2 Markup
>> object? I made it returning a unicode for now. I added some tests as
>> well.
>>
>> Thanks,
>> Zahari
>
> Markup() is pointless unless combined with escaping of markup, automatic
> or not. If you have a function for escaping markup, given an object that
> implements __html__, that method should be used unescaped. If you have
> automatic escaping (and you should) of strings used as content in a tag,
> the same logic applies. You don't need to reimplement Markup(), you can
> just from flask import Markup.
>
>>>> html.p('<em>Example</em>')
> '<p><em>Example</em></p>'
>>>> html.p(Markup('<em>Example</em>'))
> '<p><em>Example</em></p>'
>
> Flask's Markup() is just a subclass of unicode, adding __html__.
>
> If for some reason you want a html.safe() even though that's just a
> longer version of Markup() :) you just make it return Markup().
>
>

Thanks for pointing those out -- more things to be considered then.
BTW, Markup is painfully slow, and that is a concern to me, but
anyway, let see...

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 08:48
On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>>> <armin.ronacher@active-4.com> wrote:
>>> > Hi,
>>> >
>>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
>>> >> something. html.safe is quite a simple operation in my extension -
>>> >> just returning a string as is without escaping it.
>>> > Make sure to support Markup or its impossible for this extension to ever
>>> > get a seal of approval :)
>>> >
>>>
>>> I committed Markup support but I am a bit confused about whether my
>>> __html__ method should return just a unicode string or a jinja2 Markup
>>> object? I made it returning a unicode for now. I added some tests as
>>> well.
>>>
>>> Thanks,
>>> Zahari
>>
>> Markup() is pointless unless combined with escaping of markup, automatic
>> or not. If you have a function for escaping markup, given an object that
>> implements __html__, that method should be used unescaped. If you have
>> automatic escaping (and you should) of strings used as content in a tag,
>> the same logic applies. You don't need to reimplement Markup(), you can
>> just from flask import Markup.
>>
>>>>> html.p('<em>Example</em>')
>> '<p><em>Example</em></p>'
>>>>> html.p(Markup('<em>Example</em>'))
>> '<p><em>Example</em></p>'
>>
>> Flask's Markup() is just a subclass of unicode, adding __html__.
>>
>> If for some reason you want a html.safe() even though that's just a
>> longer version of Markup() :) you just make it return Markup().
>>
>
> Thanks for pointing those out -- more things to be considered then.
> BTW, Markup is painfully slow, and that is a concern to me, but
> anyway, let see...
>

I was not aware till that moment, that besides side-effect, there are
a few specialized versions - left side-effect, right side-effect, and,
yes, the one that comes from left and from right simultaneously.

Well, I am a bit troubled here :)

>>> from jinja2 import Markup
>>> Markup(' ')
Markup(u' ')

Okay...

>>> ' ' + Markup(' ')
Markup(u'&nbsp; ')

Meh!?

>>> ' ' + Markup(' ') + ' '
Markup(u'&nbsp; &nbsp;')

Wow, it is spreading like a decease :-D Okay, that was funny (for me
at least) but I think this is a serous design flaw..

Since Markup is overloading `unicode`, it should not change so
drastically it's protocol behavior, and now it is definitely not a
`unicode` instance which should be by definition of class overloading.
It is a monster eating strings and escaping them in it's belly :-D
Why?

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Armin Ronacher
Date:
2010-11-09 @ 15:02
Hi,

On 2010-11-09 9:48 AM, Zahari Petkov wrote:
>>>> ' ' + Markup(' ')
> Markup(u'&nbsp; ')
>
> Meh!?
>
>>>> ' ' + Markup(' ') + ' '
> Markup(u'&nbsp; &nbsp;')
>
> Wow, it is spreading like a decease :-D Okay, that was funny (for me
> at least) but I think this is a serous design flaw..
That's not a design flaw, that's the whole point.

  >>> Markup(u'<strong>%s</strong>') % '<foo>'
  Markup(u'<strong><foo></strong>')


Regards,
Armin

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 16:09
> That's not a design flaw, that's the whole point.
>
>  >>> Markup(u'<strong>%s</strong>') % '<foo>'
>  Markup(u'<strong><foo></strong>')
>
>
> Regards,
> Armin
>

Yes, I was wrong. I was thinking in a too dogmatic way with some OOP
concepts in my mind. Looking at the bigger picture, I think the Markup
class as a whole is quite innovative and doing the job well. Sorry
about stirring the discussion in the wrong direction, I will be more
careful next time.

Anyway, I will look further what my implementation is still missing
and set those right. I am working on some cool things with it now and
I think the outcome will be quite good.

I appreciate the help extended from various members of the community a
lot and thanks for that guys.
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-09 @ 09:31
On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
> >>> <armin.ronacher@active-4.com> wrote:
> >>> > Hi,
> >>> >
> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
> >>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
> >>> >> something. html.safe is quite a simple operation in my extension -
> >>> >> just returning a string as is without escaping it.
> >>> > Make sure to support Markup or its impossible for this extension to ever
> >>> > get a seal of approval :)
> >>> >
> >>>
> >>> I committed Markup support but I am a bit confused about whether my
> >>> __html__ method should return just a unicode string or a jinja2 Markup
> >>> object? I made it returning a unicode for now. I added some tests as
> >>> well.
> >>>
> >>> Thanks,
> >>> Zahari
> >>
> >> Markup() is pointless unless combined with escaping of markup, automatic
> >> or not. If you have a function for escaping markup, given an object that
> >> implements __html__, that method should be used unescaped. If you have
> >> automatic escaping (and you should) of strings used as content in a tag,
> >> the same logic applies. You don't need to reimplement Markup(), you can
> >> just from flask import Markup.
> >>
> >>>>> html.p('<em>Example</em>')
> >> '<p><em>Example</em></p>'
> >>>>> html.p(Markup('<em>Example</em>'))
> >> '<p><em>Example</em></p>'
> >>
> >> Flask's Markup() is just a subclass of unicode, adding __html__.
> >>
> >> If for some reason you want a html.safe() even though that's just a
> >> longer version of Markup() :) you just make it return Markup().
> >>
> >
> > Thanks for pointing those out -- more things to be considered then.
> > BTW, Markup is painfully slow, and that is a concern to me, but
> > anyway, let see...
> >
> 
> I was not aware till that moment, that besides side-effect, there are
> a few specialized versions - left side-effect, right side-effect, and,
> yes, the one that comes from left and from right simultaneously.
> 
> Well, I am a bit troubled here :)
> 
> >>> from jinja2 import Markup
> >>> Markup(' ')
> Markup(u' ')
> 
> Okay...
> 
> >>> ' ' + Markup(' ')
> Markup(u'&nbsp; ')
> 
> Meh!?
> 
> >>> ' ' + Markup(' ') + ' '
> Markup(u'&nbsp; &nbsp;')
> 
> Wow, it is spreading like a decease :-D Okay, that was funny (for me
> at least) but I think this is a serous design flaw..
> 
> Since Markup is overloading `unicode`, it should not change so
> drastically it's protocol behavior, and now it is definitely not a
> `unicode` instance which should be by definition of class overloading.
> It is a monster eating strings and escaping them in it's belly :-D
> Why?
> 
> Thanks,
> Zahari

It's intentional, only what is explicitly Markup() is "safe" and left
unescaped.

>>> Markup(' ') + Markup(' ')
Markup(u'  ')

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 10:13
On Tue, Nov 9, 2010 at 11:31 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
>> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>> >>> <armin.ronacher@active-4.com> wrote:
>> >>> > Hi,
>> >>> >
>> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>> >>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> >>> >> something. html.safe is quite a simple operation in my extension -
>> >>> >> just returning a string as is without escaping it.
>> >>> > Make sure to support Markup or its impossible for this extension to ever
>> >>> > get a seal of approval :)
>> >>> >
>> >>>
>> >>> I committed Markup support but I am a bit confused about whether my
>> >>> __html__ method should return just a unicode string or a jinja2 Markup
>> >>> object? I made it returning a unicode for now. I added some tests as
>> >>> well.
>> >>>
>> >>> Thanks,
>> >>> Zahari
>> >>
>> >> Markup() is pointless unless combined with escaping of markup, automatic
>> >> or not. If you have a function for escaping markup, given an object that
>> >> implements __html__, that method should be used unescaped. If you have
>> >> automatic escaping (and you should) of strings used as content in a tag,
>> >> the same logic applies. You don't need to reimplement Markup(), you can
>> >> just from flask import Markup.
>> >>
>> >>>>> html.p('<em>Example</em>')
>> >> '<p><em>Example</em></p>'
>> >>>>> html.p(Markup('<em>Example</em>'))
>> >> '<p><em>Example</em></p>'
>> >>
>> >> Flask's Markup() is just a subclass of unicode, adding __html__.
>> >>
>> >> If for some reason you want a html.safe() even though that's just a
>> >> longer version of Markup() :) you just make it return Markup().
>> >>
>> >
>> > Thanks for pointing those out -- more things to be considered then.
>> > BTW, Markup is painfully slow, and that is a concern to me, but
>> > anyway, let see...
>> >
>>
>> I was not aware till that moment, that besides side-effect, there are
>> a few specialized versions - left side-effect, right side-effect, and,
>> yes, the one that comes from left and from right simultaneously.
>>
>> Well, I am a bit troubled here :)
>>
>> >>> from jinja2 import Markup
>> >>> Markup(' ')
>> Markup(u' ')
>>
>> Okay...
>>
>> >>> ' ' + Markup(' ')
>> Markup(u'&nbsp; ')
>>
>> Meh!?
>>
>> >>> ' ' + Markup(' ') + ' '
>> Markup(u'&nbsp; &nbsp;')
>>
>> Wow, it is spreading like a decease :-D Okay, that was funny (for me
>> at least) but I think this is a serous design flaw..
>>
>> Since Markup is overloading `unicode`, it should not change so
>> drastically it's protocol behavior, and now it is definitely not a
>> `unicode` instance which should be by definition of class overloading.
>> It is a monster eating strings and escaping them in it's belly :-D
>> Why?
>>
>> Thanks,
>> Zahari
>
> It's intentional, only what is explicitly Markup() is "safe" and left
> unescaped.
>

I see it is intentional and the purpose is obvious. I am questioning
the design decisions made, and more specifically I am asking whether I
should protect myself from them or not :)

Even if `Markup` was not a sub-class of  `unicode`, which is
definitely a hack disregarding basic principles of OOP (that's fine,
everyone is free to break a couple of rules). that is still pretty
aggressive behavior, which forces me into two possible directions:

1. protecting my extension against such aggressiveness. If that is
okay, I am okay as well.
2. adopting it, which will lead to a significant performance penalty,
which I am not eager to sacrifice.

Basically, when someone is telling me that everything is internally
converted to `unicode`, so that I do not worry about encoding
exceptions, and my text that should not be escaped should stay
un-escaped whatever we try to do to it, it reads to me the following:
you will get a significant penalty by multiple `unicode`
instantiations, because we are taking care of you not to do stupid
things. And sometimes it reads that we are not 100% sure what's going
on inside our code, or we just think this is the only way to go, and
we will trade speed for stability. But when I use Jinja 2 `escape`
which uses `Markup`, and when I run the Big Table performance test, my
extension is 4x slower. This is a huge trade-off for me, and I am not
eager to sacrifice it. I am not criticizing the design decisions made,
actually, they are just not suitable for me to adopt them.

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Dag Odenhall
Date:
2010-11-09 @ 11:18
On Tue, 2010-11-09 at 12:13 +0200, Zahari Petkov wrote:
> On Tue, Nov 9, 2010 at 11:31 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> > On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
> >> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> >> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall 
<dag.odenhall@gmail.com> wrote:
> >> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
> >> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
> >> >>> <armin.ronacher@active-4.com> wrote:
> >> >>> > Hi,
> >> >>> >
> >> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
> >> >>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
> >> >>> >> something. html.safe is quite a simple operation in my extension -
> >> >>> >> just returning a string as is without escaping it.
> >> >>> > Make sure to support Markup or its impossible for this 
extension to ever
> >> >>> > get a seal of approval :)
> >> >>> >
> >> >>>
> >> >>> I committed Markup support but I am a bit confused about whether my
> >> >>> __html__ method should return just a unicode string or a jinja2 Markup
> >> >>> object? I made it returning a unicode for now. I added some tests as
> >> >>> well.
> >> >>>
> >> >>> Thanks,
> >> >>> Zahari
> >> >>
> >> >> Markup() is pointless unless combined with escaping of markup, automatic
> >> >> or not. If you have a function for escaping markup, given an object that
> >> >> implements __html__, that method should be used unescaped. If you have
> >> >> automatic escaping (and you should) of strings used as content in a tag,
> >> >> the same logic applies. You don't need to reimplement Markup(), you can
> >> >> just from flask import Markup.
> >> >>
> >> >>>>> html.p('<em>Example</em>')
> >> >> '<p><em>Example</em></p>'
> >> >>>>> html.p(Markup('<em>Example</em>'))
> >> >> '<p><em>Example</em></p>'
> >> >>
> >> >> Flask's Markup() is just a subclass of unicode, adding __html__.
> >> >>
> >> >> If for some reason you want a html.safe() even though that's just a
> >> >> longer version of Markup() :) you just make it return Markup().
> >> >>
> >> >
> >> > Thanks for pointing those out -- more things to be considered then.
> >> > BTW, Markup is painfully slow, and that is a concern to me, but
> >> > anyway, let see...
> >> >
> >>
> >> I was not aware till that moment, that besides side-effect, there are
> >> a few specialized versions - left side-effect, right side-effect, and,
> >> yes, the one that comes from left and from right simultaneously.
> >>
> >> Well, I am a bit troubled here :)
> >>
> >> >>> from jinja2 import Markup
> >> >>> Markup(' ')
> >> Markup(u' ')
> >>
> >> Okay...
> >>
> >> >>> ' ' + Markup(' ')
> >> Markup(u'&nbsp; ')
> >>
> >> Meh!?
> >>
> >> >>> ' ' + Markup(' ') + ' '
> >> Markup(u'&nbsp; &nbsp;')
> >>
> >> Wow, it is spreading like a decease :-D Okay, that was funny (for me
> >> at least) but I think this is a serous design flaw..
> >>
> >> Since Markup is overloading `unicode`, it should not change so
> >> drastically it's protocol behavior, and now it is definitely not a
> >> `unicode` instance which should be by definition of class overloading.
> >> It is a monster eating strings and escaping them in it's belly :-D
> >> Why?
> >>
> >> Thanks,
> >> Zahari
> >
> > It's intentional, only what is explicitly Markup() is "safe" and left
> > unescaped.
> >
> 
> I see it is intentional and the purpose is obvious. I am questioning
> the design decisions made, and more specifically I am asking whether I
> should protect myself from them or not :)
> 
> Even if `Markup` was not a sub-class of  `unicode`, which is
> definitely a hack disregarding basic principles of OOP (that's fine,
> everyone is free to break a couple of rules). that is still pretty
> aggressive behavior, which forces me into two possible directions:
> 
> 1. protecting my extension against such aggressiveness. If that is
> okay, I am okay as well.
> 2. adopting it, which will lead to a significant performance penalty,
> which I am not eager to sacrifice.
> 
> Basically, when someone is telling me that everything is internally
> converted to `unicode`, so that I do not worry about encoding
> exceptions, and my text that should not be escaped should stay
> un-escaped whatever we try to do to it, it reads to me the following:
> you will get a significant penalty by multiple `unicode`
> instantiations, because we are taking care of you not to do stupid
> things. And sometimes it reads that we are not 100% sure what's going
> on inside our code, or we just think this is the only way to go, and
> we will trade speed for stability. But when I use Jinja 2 `escape`
> which uses `Markup`, and when I run the Big Table performance test, my
> extension is 4x slower. This is a huge trade-off for me, and I am not
> eager to sacrifice it. I am not criticizing the design decisions made,
> actually, they are just not suitable for me to adopt them.
> 
> Thanks,
> Zahari

Have you tried benchmarking after installing the MarkupSafe package? It
has a C extension for speedups and Jinja bundles it without the
speedups, but it will use the package if it is installed.

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 11:26
On Tue, Nov 9, 2010 at 1:18 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
> On Tue, 2010-11-09 at 12:13 +0200, Zahari Petkov wrote:
>> On Tue, Nov 9, 2010 at 11:31 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> > On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
>> >> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>> >> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall 
<dag.odenhall@gmail.com> wrote:
>> >> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>> >> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>> >> >>> <armin.ronacher@active-4.com> wrote:
>> >> >>> > Hi,
>> >> >>> >
>> >> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>> >> >>> >> I will look at Markup of Jinja and Genshi, to see whether I 
am missing
>> >> >>> >> something. html.safe is quite a simple operation in my extension -
>> >> >>> >> just returning a string as is without escaping it.
>> >> >>> > Make sure to support Markup or its impossible for this 
extension to ever
>> >> >>> > get a seal of approval :)
>> >> >>> >
>> >> >>>
>> >> >>> I committed Markup support but I am a bit confused about whether my
>> >> >>> __html__ method should return just a unicode string or a jinja2 Markup
>> >> >>> object? I made it returning a unicode for now. I added some tests as
>> >> >>> well.
>> >> >>>
>> >> >>> Thanks,
>> >> >>> Zahari
>> >> >>
>> >> >> Markup() is pointless unless combined with escaping of markup, automatic
>> >> >> or not. If you have a function for escaping markup, given an object that
>> >> >> implements __html__, that method should be used unescaped. If you have
>> >> >> automatic escaping (and you should) of strings used as content in a tag,
>> >> >> the same logic applies. You don't need to reimplement Markup(), you can
>> >> >> just from flask import Markup.
>> >> >>
>> >> >>>>> html.p('<em>Example</em>')
>> >> >> '<p><em>Example</em></p>'
>> >> >>>>> html.p(Markup('<em>Example</em>'))
>> >> >> '<p><em>Example</em></p>'
>> >> >>
>> >> >> Flask's Markup() is just a subclass of unicode, adding __html__.
>> >> >>
>> >> >> If for some reason you want a html.safe() even though that's just a
>> >> >> longer version of Markup() :) you just make it return Markup().
>> >> >>
>> >> >
>> >> > Thanks for pointing those out -- more things to be considered then.
>> >> > BTW, Markup is painfully slow, and that is a concern to me, but
>> >> > anyway, let see...
>> >> >
>> >>
>> >> I was not aware till that moment, that besides side-effect, there are
>> >> a few specialized versions - left side-effect, right side-effect, and,
>> >> yes, the one that comes from left and from right simultaneously.
>> >>
>> >> Well, I am a bit troubled here :)
>> >>
>> >> >>> from jinja2 import Markup
>> >> >>> Markup(' ')
>> >> Markup(u' ')
>> >>
>> >> Okay...
>> >>
>> >> >>> ' ' + Markup(' ')
>> >> Markup(u'&nbsp; ')
>> >>
>> >> Meh!?
>> >>
>> >> >>> ' ' + Markup(' ') + ' '
>> >> Markup(u'&nbsp; &nbsp;')
>> >>
>> >> Wow, it is spreading like a decease :-D Okay, that was funny (for me
>> >> at least) but I think this is a serous design flaw..
>> >>
>> >> Since Markup is overloading `unicode`, it should not change so
>> >> drastically it's protocol behavior, and now it is definitely not a
>> >> `unicode` instance which should be by definition of class overloading.
>> >> It is a monster eating strings and escaping them in it's belly :-D
>> >> Why?
>> >>
>> >> Thanks,
>> >> Zahari
>> >
>> > It's intentional, only what is explicitly Markup() is "safe" and left
>> > unescaped.
>> >
>>
>> I see it is intentional and the purpose is obvious. I am questioning
>> the design decisions made, and more specifically I am asking whether I
>> should protect myself from them or not :)
>>
>> Even if `Markup` was not a sub-class of  `unicode`, which is
>> definitely a hack disregarding basic principles of OOP (that's fine,
>> everyone is free to break a couple of rules). that is still pretty
>> aggressive behavior, which forces me into two possible directions:
>>
>> 1. protecting my extension against such aggressiveness. If that is
>> okay, I am okay as well.
>> 2. adopting it, which will lead to a significant performance penalty,
>> which I am not eager to sacrifice.
>>
>> Basically, when someone is telling me that everything is internally
>> converted to `unicode`, so that I do not worry about encoding
>> exceptions, and my text that should not be escaped should stay
>> un-escaped whatever we try to do to it, it reads to me the following:
>> you will get a significant penalty by multiple `unicode`
>> instantiations, because we are taking care of you not to do stupid
>> things. And sometimes it reads that we are not 100% sure what's going
>> on inside our code, or we just think this is the only way to go, and
>> we will trade speed for stability. But when I use Jinja 2 `escape`
>> which uses `Markup`, and when I run the Big Table performance test, my
>> extension is 4x slower. This is a huge trade-off for me, and I am not
>> eager to sacrifice it. I am not criticizing the design decisions made,
>> actually, they are just not suitable for me to adopt them.
>>
>> Thanks,
>> Zahari
>
> Have you tried benchmarking after installing the MarkupSafe package? It
> has a C extension for speedups and Jinja bundles it without the
> speedups, but it will use the package if it is installed.
>
>

Nope, actually, my laptop motherboard died a couple of weeks ago and I
am now using an old XP machine. I did not found the Jinja 2 speedups
for win32 in a pre-compiled package, and VMs are quite a pain with so
less RAM to run Ubuntu now. Additionally there is no C stuff allowed
on GAE, and there is where you pay for CPU, which alone is enough for
me to disregard that as an option.

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 12:00
On Tue, Nov 9, 2010 at 1:26 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> On Tue, Nov 9, 2010 at 1:18 PM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> On Tue, 2010-11-09 at 12:13 +0200, Zahari Petkov wrote:
>>> On Tue, Nov 9, 2010 at 11:31 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>>> > On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
>>> >> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>>> >> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall 
<dag.odenhall@gmail.com> wrote:
>>> >> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>>> >> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>>> >> >>> <armin.ronacher@active-4.com> wrote:
>>> >> >>> > Hi,
>>> >> >>> >
>>> >> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>>> >> >>> >> I will look at Markup of Jinja and Genshi, to see whether I 
am missing
>>> >> >>> >> something. html.safe is quite a simple operation in my extension -
>>> >> >>> >> just returning a string as is without escaping it.
>>> >> >>> > Make sure to support Markup or its impossible for this 
extension to ever
>>> >> >>> > get a seal of approval :)
>>> >> >>> >
>>> >> >>>
>>> >> >>> I committed Markup support but I am a bit confused about whether my
>>> >> >>> __html__ method should return just a unicode string or a jinja2 Markup
>>> >> >>> object? I made it returning a unicode for now. I added some tests as
>>> >> >>> well.
>>> >> >>>
>>> >> >>> Thanks,
>>> >> >>> Zahari
>>> >> >>
>>> >> >> Markup() is pointless unless combined with escaping of markup, automatic
>>> >> >> or not. If you have a function for escaping markup, given an object that
>>> >> >> implements __html__, that method should be used unescaped. If you have
>>> >> >> automatic escaping (and you should) of strings used as content in a tag,
>>> >> >> the same logic applies. You don't need to reimplement Markup(), you can
>>> >> >> just from flask import Markup.
>>> >> >>
>>> >> >>>>> html.p('<em>Example</em>')
>>> >> >> '<p><em>Example</em></p>'
>>> >> >>>>> html.p(Markup('<em>Example</em>'))
>>> >> >> '<p><em>Example</em></p>'
>>> >> >>
>>> >> >> Flask's Markup() is just a subclass of unicode, adding __html__.
>>> >> >>
>>> >> >> If for some reason you want a html.safe() even though that's just a
>>> >> >> longer version of Markup() :) you just make it return Markup().
>>> >> >>
>>> >> >
>>> >> > Thanks for pointing those out -- more things to be considered then.
>>> >> > BTW, Markup is painfully slow, and that is a concern to me, but
>>> >> > anyway, let see...
>>> >> >
>>> >>
>>> >> I was not aware till that moment, that besides side-effect, there are
>>> >> a few specialized versions - left side-effect, right side-effect, and,
>>> >> yes, the one that comes from left and from right simultaneously.
>>> >>
>>> >> Well, I am a bit troubled here :)
>>> >>
>>> >> >>> from jinja2 import Markup
>>> >> >>> Markup(' ')
>>> >> Markup(u' ')
>>> >>
>>> >> Okay...
>>> >>
>>> >> >>> ' ' + Markup(' ')
>>> >> Markup(u'&nbsp; ')
>>> >>
>>> >> Meh!?
>>> >>
>>> >> >>> ' ' + Markup(' ') + ' '
>>> >> Markup(u'&nbsp; &nbsp;')
>>> >>
>>> >> Wow, it is spreading like a decease :-D Okay, that was funny (for me
>>> >> at least) but I think this is a serous design flaw..
>>> >>
>>> >> Since Markup is overloading `unicode`, it should not change so
>>> >> drastically it's protocol behavior, and now it is definitely not a
>>> >> `unicode` instance which should be by definition of class overloading.
>>> >> It is a monster eating strings and escaping them in it's belly :-D
>>> >> Why?
>>> >>
>>> >> Thanks,
>>> >> Zahari
>>> >
>>> > It's intentional, only what is explicitly Markup() is "safe" and left
>>> > unescaped.
>>> >
>>>
>>> I see it is intentional and the purpose is obvious. I am questioning
>>> the design decisions made, and more specifically I am asking whether I
>>> should protect myself from them or not :)
>>>
>>> Even if `Markup` was not a sub-class of  `unicode`, which is
>>> definitely a hack disregarding basic principles of OOP (that's fine,
>>> everyone is free to break a couple of rules). that is still pretty
>>> aggressive behavior, which forces me into two possible directions:
>>>
>>> 1. protecting my extension against such aggressiveness. If that is
>>> okay, I am okay as well.
>>> 2. adopting it, which will lead to a significant performance penalty,
>>> which I am not eager to sacrifice.
>>>
>>> Basically, when someone is telling me that everything is internally
>>> converted to `unicode`, so that I do not worry about encoding
>>> exceptions, and my text that should not be escaped should stay
>>> un-escaped whatever we try to do to it, it reads to me the following:
>>> you will get a significant penalty by multiple `unicode`
>>> instantiations, because we are taking care of you not to do stupid
>>> things. And sometimes it reads that we are not 100% sure what's going
>>> on inside our code, or we just think this is the only way to go, and
>>> we will trade speed for stability. But when I use Jinja 2 `escape`
>>> which uses `Markup`, and when I run the Big Table performance test, my
>>> extension is 4x slower. This is a huge trade-off for me, and I am not
>>> eager to sacrifice it. I am not criticizing the design decisions made,
>>> actually, they are just not suitable for me to adopt them.
>>>
>>> Thanks,
>>> Zahari
>>
>> Have you tried benchmarking after installing the MarkupSafe package? It
>> has a C extension for speedups and Jinja bundles it without the
>> speedups, but it will use the package if it is installed.
>>
>>
>
> Nope, actually, my laptop motherboard died a couple of weeks ago and I
> am now using an old XP machine. I did not found the Jinja 2 speedups
> for win32 in a pre-compiled package, and VMs are quite a pain with so
> less RAM to run Ubuntu now. Additionally there is no C stuff allowed
> on GAE, and there is where you pay for CPU, which alone is enough for
> me to disregard that as an option.
>

All that said, I do not see any contradiction anyway in the approach I
took. Werkzeug HTMLBuilder is doing the same. They just are friendly
to Markup, without adopting it fully.

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-09 @ 11:10
On Tue, Nov 9, 2010 at 12:13 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> On Tue, Nov 9, 2010 at 11:31 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>> On Tue, 2010-11-09 at 10:48 +0200, Zahari Petkov wrote:
>>> On Tue, Nov 9, 2010 at 9:54 AM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>>> > On Tue, Nov 9, 2010 at 9:33 AM, Dag Odenhall <dag.odenhall@gmail.com> wrote:
>>> >> On Tue, 2010-11-09 at 03:02 +0200, Zahari Petkov wrote:
>>> >>> On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
>>> >>> <armin.ronacher@active-4.com> wrote:
>>> >>> > Hi,
>>> >>> >
>>> >>> > On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>>> >>> >> I will look at Markup of Jinja and Genshi, to see whether I am missing
>>> >>> >> something. html.safe is quite a simple operation in my extension -
>>> >>> >> just returning a string as is without escaping it.
>>> >>> > Make sure to support Markup or its impossible for this extension to ever
>>> >>> > get a seal of approval :)
>>> >>> >
>>> >>>
>>> >>> I committed Markup support but I am a bit confused about whether my
>>> >>> __html__ method should return just a unicode string or a jinja2 Markup
>>> >>> object? I made it returning a unicode for now. I added some tests as
>>> >>> well.
>>> >>>
>>> >>> Thanks,
>>> >>> Zahari
>>> >>
>>> >> Markup() is pointless unless combined with escaping of markup, automatic
>>> >> or not. If you have a function for escaping markup, given an object that
>>> >> implements __html__, that method should be used unescaped. If you have
>>> >> automatic escaping (and you should) of strings used as content in a tag,
>>> >> the same logic applies. You don't need to reimplement Markup(), you can
>>> >> just from flask import Markup.
>>> >>
>>> >>>>> html.p('<em>Example</em>')
>>> >> '<p><em>Example</em></p>'
>>> >>>>> html.p(Markup('<em>Example</em>'))
>>> >> '<p><em>Example</em></p>'
>>> >>
>>> >> Flask's Markup() is just a subclass of unicode, adding __html__.
>>> >>
>>> >> If for some reason you want a html.safe() even though that's just a
>>> >> longer version of Markup() :) you just make it return Markup().
>>> >>
>>> >
>>> > Thanks for pointing those out -- more things to be considered then.
>>> > BTW, Markup is painfully slow, and that is a concern to me, but
>>> > anyway, let see...
>>> >
>>>
>>> I was not aware till that moment, that besides side-effect, there are
>>> a few specialized versions - left side-effect, right side-effect, and,
>>> yes, the one that comes from left and from right simultaneously.
>>>
>>> Well, I am a bit troubled here :)
>>>
>>> >>> from jinja2 import Markup
>>> >>> Markup(' ')
>>> Markup(u' ')
>>>
>>> Okay...
>>>
>>> >>> ' ' + Markup(' ')
>>> Markup(u'&nbsp; ')
>>>
>>> Meh!?
>>>
>>> >>> ' ' + Markup(' ') + ' '
>>> Markup(u'&nbsp; &nbsp;')
>>>
>>> Wow, it is spreading like a decease :-D Okay, that was funny (for me
>>> at least) but I think this is a serous design flaw..
>>>
>>> Since Markup is overloading `unicode`, it should not change so
>>> drastically it's protocol behavior, and now it is definitely not a
>>> `unicode` instance which should be by definition of class overloading.
>>> It is a monster eating strings and escaping them in it's belly :-D
>>> Why?
>>>
>>> Thanks,
>>> Zahari
>>
>> It's intentional, only what is explicitly Markup() is "safe" and left
>> unescaped.
>>
>
> I see it is intentional and the purpose is obvious. I am questioning
> the design decisions made, and more specifically I am asking whether I
> should protect myself from them or not :)
>
> Even if `Markup` was not a sub-class of  `unicode`, which is
> definitely a hack disregarding basic principles of OOP (that's fine,
> everyone is free to break a couple of rules). that is still pretty
> aggressive behavior, which forces me into two possible directions:
>
> 1. protecting my extension against such aggressiveness. If that is
> okay, I am okay as well.
> 2. adopting it, which will lead to a significant performance penalty,
> which I am not eager to sacrifice.
>
> Basically, when someone is telling me that everything is internally
> converted to `unicode`, so that I do not worry about encoding
> exceptions, and my text that should not be escaped should stay
> un-escaped whatever we try to do to it, it reads to me the following:
> you will get a significant penalty by multiple `unicode`
> instantiations, because we are taking care of you not to do stupid
> things. And sometimes it reads that we are not 100% sure what's going
> on inside our code, or we just think this is the only way to go, and
> we will trade speed for stability. But when I use Jinja 2 `escape`
> which uses `Markup`, and when I run the Big Table performance test, my
> extension is 4x slower. This is a huge trade-off for me, and I am not
> eager to sacrifice it. I am not criticizing the design decisions made,
> actually, they are just not suitable for me to adopt them.
>
> Thanks,
> Zahari
>

I committed full support for Markup:
>>> str(html.p(Markup('<strong> Text </strong>'))))
'<p><strong> Text </strong></p>'
>>> str(Markup(html.p(html.safe('<strong> Text </strong>'))))
'<p><strong> Text </strong></p>'

As I said earlier I protected my extension to the aggressive Markup
behavior. Tests are working fine, I would count that task for
completed, unless some objections arise.

Thanks,
Zahari

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-08 @ 13:06
Sounds good, I will work on that now.

Thanks,
Zahari

On Mon, Nov 8, 2010 at 3:02 PM, Armin Ronacher
<armin.ronacher@active-4.com> wrote:
> Hi,
>
> On 2010-11-08 1:17 PM, Zahari Petkov wrote:
>> I will look at Markup of Jinja and Genshi, to see whether I am missing
>> something. html.safe is quite a simple operation in my extension -
>> just returning a string as is without escaping it.
> Make sure to support Markup or its impossible for this extension to ever
> get a seal of approval :)
>
>
> Regards,
> Armin
>

Re: [flask] Re: HTML Builder Flask Extension

From:
Jonas Galvez
Date:
2010-11-08 @ 05:23
Looks awesome. Nice work on the documentation.

-- Jonas

On Sun, Nov 7, 2010 at 9:32 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:

> Hey guys,
>
> I just committed my Flask-HTMLBuilder extension:
> source: http://github.com/majorz/flask-htmlbuilder
> documentation: http://majorz.github.com/flask-htmlbuilder/
>
> I used the Flask extension generator for initial skeleton creation.
> Documentation is using flask_small theme. I tried to follow closely
> the recommendations and looked how other extensions were done. I would
> to ask for an initial review process.
>
> Thanks,
> Zahari
>
> On Tue, Nov 2, 2010 at 7:39 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
> > Hello,
> >
> > I am working on a HTML builder type Flask extension, similar to the
> > HTML builder in Werkzeug, but with more features, which target full
> > HTML document generation. It has support for HTML comments, doctype
> > definition, and both escaped/unescaped HTML text, etc. It takes
> > advantage of the Werkzeug endpoint system and defines template
> > inheritance mechanisms using decorators around it. I targeted
> > real-world HTML document generation with that.
> >
> > The source is still in a private repository, since I need to clean
> > that up as much as possible and make sure test coverage is full, but I
> > wrote a short use case application in which I included detailed
> > description:
> > https://gist.github.com/f5de9c33341400cc01b6
> >
> > I will make the repository public in the following days.
> >
> > I will be glad if I receive some feedback about it. Any comments?
> >
> > Regards,
> > Zahari
> >
>

Re: [flask] Re: HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-08 @ 12:21
Thanks for the nice words Jonas, writing that documentation was time
consuming, but necessary. I will improve it further, and I will add an
examples (or contrib) folder with some real-world edgy HTML, so that
people may get started even quicker using it.

Zahari

On Mon, Nov 8, 2010 at 7:23 AM, Jonas Galvez <jonasgalvez@gmail.com> wrote:
> Looks awesome. Nice work on the documentation.
> -- Jonas
>
> On Sun, Nov 7, 2010 at 9:32 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>>
>> Hey guys,
>>
>> I just committed my Flask-HTMLBuilder extension:
>> source: http://github.com/majorz/flask-htmlbuilder
>> documentation: http://majorz.github.com/flask-htmlbuilder/
>>
>> I used the Flask extension generator for initial skeleton creation.
>> Documentation is using flask_small theme. I tried to follow closely
>> the recommendations and looked how other extensions were done. I would
>> to ask for an initial review process.
>>
>> Thanks,
>> Zahari
>>
>> On Tue, Nov 2, 2010 at 7:39 PM, Zahari Petkov <zarchaoz@gmail.com> wrote:
>> > Hello,
>> >
>> > I am working on a HTML builder type Flask extension, similar to the
>> > HTML builder in Werkzeug, but with more features, which target full
>> > HTML document generation. It has support for HTML comments, doctype
>> > definition, and both escaped/unescaped HTML text, etc. It takes
>> > advantage of the Werkzeug endpoint system and defines template
>> > inheritance mechanisms using decorators around it. I targeted
>> > real-world HTML document generation with that.
>> >
>> > The source is still in a private repository, since I need to clean
>> > that up as much as possible and make sure test coverage is full, but I
>> > wrote a short use case application in which I included detailed
>> > description:
>> > https://gist.github.com/f5de9c33341400cc01b6
>> >
>> > I will make the repository public in the following days.
>> >
>> > I will be glad if I receive some feedback about it. Any comments?
>> >
>> > Regards,
>> > Zahari
>> >
>
>

Re: [flask] HTML Builder Flask Extension

From:
Jonas Galvez
Date:
2010-11-02 @ 20:48
Zahari Petkov wrote:
> I will be glad if I receive some feedback about it. Any comments?

You might want to try html5witch[1]. I've been meaning to write a
Flask extension for it for some time now, but haven't gotten around to
it yet.

One particularly interesting feature I'm thinking of is being able to
keep standalone "html.py" templates with zero boilerplate, by using
Python 2.7's runpy.run_path() method[2]. Here's a very crude (and
untested) example of how it could work:

Inside templates/index.html.py:

with doc.html:
  with doc.head:
    doc.title('Title')
  with doc.body:
    doc.p('Hello World')

Inside app.py:

@app.route('/')
def index():
   doc = html5witch.builder()
   template = runpy.run_path('templates/index.html.py', init_globals=locals())
   return Response(str(template.doc), 200)

--Jonas

[1] http://github.com/galvez/html5witch
[2] http://docs.python.org/library/runpy.html

Re: [flask] HTML Builder Flask Extension

From:
Zahari Petkov
Date:
2010-11-02 @ 21:48
Hey Jonas,

I looked at your implementation a while ago and actually liked the
indentation approach you took and borrowed the idea :)

The with statement approach you are using is interesting and I like
the innovation in it, but I prefer to stick with my current syntax. I
will definitely follow your ongoing work with interest.

Thanks,
Zahari

On Tue, Nov 2, 2010 at 10:48 PM, Jonas Galvez <jonasgalvez@gmail.com> wrote:
> Zahari Petkov wrote:
>> I will be glad if I receive some feedback about it. Any comments?
>
> You might want to try html5witch[1]. I've been meaning to write a
> Flask extension for it for some time now, but haven't gotten around to
> it yet.
>
> One particularly interesting feature I'm thinking of is being able to
> keep standalone "html.py" templates with zero boilerplate, by using
> Python 2.7's runpy.run_path() method[2]. Here's a very crude (and
> untested) example of how it could work:
>
> Inside templates/index.html.py:
>
> with doc.html:
>  with doc.head:
>    doc.title('Title')
>  with doc.body:
>    doc.p('Hello World')
>
> Inside app.py:
>
> @app.route('/')
> def index():
>   doc = html5witch.builder()
>   template = runpy.run_path('templates/index.html.py', init_globals=locals())
>   return Response(str(template.doc), 200)
>
> --Jonas
>
> [1] http://github.com/galvez/html5witch
> [2] http://docs.python.org/library/runpy.html
>