Re: Header and footer PTL Plug-in?

mario ruggier <[email protected]>
Newsgroups gmane.comp.web.quixote.user
Message-ID <[email protected]>
On Nov 7, 2005, at 9:30 AM, Shalabh Chaturvedi wrote:

> I'm trying to write Quixote applications that can be re-used easily. 
> So I do not want to bind the PTL templates tightly with my site 
> header, footer and other standard 'pieces' of a page. My current 
> strategy is to use:
>
> import pageui
>
> def someview [html] ():
>     pageui.header()
>
>     ...
>
>     pageui.footer()
>
> And not include pageui.ptl in this package at all. The user of this 
> app then has to create pageui.ptl and make sure it is in the 
> pythonpath. This allows me (and others) to re-use the application with 
> different headers, footers and such.
>
> 1. Is this a good approach?

I have been doing something very similar also, as I expect that anyone 
who has had to manage the building of non-trivial pages has also. I 
have been meaning to reply to this earlier, but my code is not ready 
for just posting, so I took a little time now to review what I had 
done, and write it up somewhat clearly.

One problem I see with what you propose is that what happens if an 
error occurs in teh middle of your view rendering? And, the page you 
wish to display uses a different visual style in that case.

I have a whole scheme, that tries to do a lot more than what you are 
after I think,  by which a page_info object is constructed during page 
processing, and then rendering will cause that all (css, js) x (files, 
code snippets) will be conveniently placed in the head element, 
irrespective of where they have "sprung out" from within the page, 
making page easier to load, and debug...

> 2. Is there value in standardizing the 'pageui' API? For example I end 
> up using not just header() and footer() but also msg_box(msg), 
> link_button(label, target) and other such components.

I have also included info of how I handle rather complex page 
components, that have their own behaviour and interaction. These also 
know how to talk to the page_info object.

My current implementation, for quixote, is not as clean as the partial 
description in the attached file. As I will probably be revising it 
anyway, and possibly doing it for qp, I would appreciate any comments 
you may have, even suggestions of better names. I also would be happy 
to converge this with other similar efforts that may be going on... QP 
already has a very simple idiom for rendering a page, namely that 
publisher.page() renders by calling publisher.header() and 
publisher.footer(), that are therefore easily overridden by the site's 
publisher. What I describe is actually not very different, but more 
general i think. I'd also be interested of ideas of how best to add 
this onto qp... but ill take that to that list.

mario

_______________________________________________
Quixote-users mailing list
[email protected]
http://mail.mems-exchange.org/mailman/listinfo/quixote-users
pageui.txt (text/plain, 4.1 KB)
# Idiom for building complex web pages
# Author: [email protected]

A description of an idiom for building complex web pages, that contain behaviour-rich page components. Note that this is independent of the templating being used.


# page_info ##################################################################

Each page has an info object, either defined wherever the page is defined, or in some centralized place, as preferred. A copy of this object is passed along to the request (or hit in qp) and it can be therefore modified freely during page processing, before rendering. 

A basic idea here was to maximize sanity when developing complex html pages, as well as making those complex pages as simple as they can possibly be, for the browser to handle, and for debugging. If all css and js required by a page is built in this way, then *all* of it is rendered in the page's <head>, that is therefore guaranteed to be all loaded by the time the page onload gets fired, thus shortcutting many potential annoyances. 

page_info = dict(

    '''
    We may want to have different "visual" categories of pages
    '''
    category = 'std', # 'home' | 'error' | 'data_listing' | ... 
    
    '''
    Some pages have a fixed title. This can be in and of itself a tiny 
    template, for variable substitution at page-rendering time.
    '''
    title = string, 
    
    '''
    css file names, each giving a <link rel="stylesheet"> element
    '''
    css_files = [], 
    
    '''
    css code snippets, inlined in a single <style> element
    '''
    css_codes = [], 

    '''
    js file names, each giving a <script src="..."> element
    '''
    js_files = [],  

    '''
    js code snippets, inlined in a single <script> element
    '''
    js_codes = [],  
    
    '''
    js code snippets that you want to be executed when the page is loaded.
    These are wrapped inside a function, e.g. page_onload(){}, and written
    out in the same <script> as for js_codes. Plus, if not empty, <body>      
    gets an onload="page_onload();" attribute.
    '''
    onload_actions = [], 

    '''
    Any attributes we may wish <body> to have. 
    '''
    body_attrs = dict, 
    
)


# pageui.py ##################################################################

In a separate module or modules, there will be a corresponding page/header/footer set of functions for each page category, that therefore calling:

    pageui.page(page_info, *contents, **kwargs)

will delegate calls to the appropriate functions for value of category, e.g. for an std page, the rendering will be the accumulated return values of:

    std_header(page_info, contents, kwargs)
    std_content(page_info, contents, kwargs)
    std_footer(page_info, contents, kwargs)


# page_components ############################################################

Page components are rather complex formatting objects, that may have behaviour, that may have their own content, that know nothing about forms and form widgets but have to play very nicely with any of them (they do not know if they contain widgets that belong to some form on the page, or whether they themselves contain a form in its entirety. Interaction with rest of page is key. 

Examples that I have made are CollapsableBox, TabbedSections, SortableTable, custom variations of these as well as others. 

Each page component instance has a prefix that must be unique within the page. It can then use this to derive however many names it needs, such as widget names, element ids, etc., not only without overstepping anything else on the page but also may expose these "internal" objects to others on the page.

I have a BasePageComponent class, with the constructor:

    def __init__(self, prefix='bpc', page_info=None, content=None):
    
Page components not only know how to render themselves, but also can generate specific bits of css and js that are added to page_info, as well as make sure that a special external css or js file that they need will be loaded by the page. 

Internally, they define their own "boilerplate" code, for html, js and css, and render it all as appropriate with page specific data. 


##############################################################################
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.