degal/templates.py
author Tero Marttila <terom@fixme.fi>
Wed, 01 Jul 2009 20:15:08 +0300
changeset 139 d3167c40e7b9
parent 136 29e41a6415d7
child 142 2b8dfacc6d2d
permissions -rw-r--r--
remove old scripts/cgi-bin stuff. They wouldn't work as such with the new version, and replacements can be written while referring to the history
"""
    Templates for HTML output
"""

import html, version
from html import tags

import urllib

def quote_path (path) :
    """
        Return an unicode-safe string with the escaped contents of the given str-able object, suitable for use
        in HTTP URLs.

        This should provide correct behaviour for use with filesystem Nodes.

        XXX: even this could be abstracted to some kind of "URL" thing
    """

    return urllib.quote(str(path))

def link_from (source, target) :
    """
        Returns a partial a tag linking from the given source page to the target page, escaping binary paths.
    """

    return tags.a(href=quote_path(source.path_to(target)))

def image_link (from_page, image, target) :
    """
        Link to the given image
    """

    return link_from(from_page, target)(
        tags.img(src=quote_path(image.path_from(from_page)))
    )

def image_page (image) :
    """
        The per-image view
    """

    return [
        tags.div(id='image')(
            # title
            tags.h1(image.title) if image.title else None,

            # image-links
            tags.p(
                # prev thumb
                image_link(image.html, image.prev.thumb, image.prev.html) if image.prev else None,

                # preview
                image_link(image.html, image.preview, image),

                # next thumb
                image_link(image.html, image.next.thumb, image.next.html) if image.next else None
            ),

            # optional description
            tags.p(image.description) if image.description else None,
        ),

        # extended info, metadata
        tags.div(id='info')(*(
            tags.p(("%s: " % name), value) for name, value in image.metadata
        )),
    ]

def folder_link (from_page, folder, page=0) :
    """
        Returns a link to the given folder from the given page
    """

    return link_from(from_page, folder.html_page(page))(folder.title)

def folder_page_link (folder, page) :
    """
        Returns a partial a tag from the folder itself to the given page number
    """

    return link_from(folder, folder.html_page(page))

def folder_paginate (folder, cur_page) :
    """
        Render the pagination view for a folder, if needed
    """
    
    if folder.page_count > 1 :
        return tags.div(class_='paginate')(
            tags.ul(
                # prev link
                tags.li(folder_page_link(folder, cur_page - 1)(html.raw("&laquo; Prev")))
                    if cur_page > 0 else
                tags.li(tags.span(html.raw("&laquo; Prev"))),
                
                ((
                    # page link
                    tags.li(folder_page_link(folder, page)(page + 1))
                        if page != cur_page else
                    tags.li(tags.strong(page + 1))
                ) for page in xrange(folder.page_count)),
                
                # next link
                tags.li(folder_page_link(folder, cur_page + 1)(html.raw("Next &raquo;")))
                    if cur_page < folder.page_count - 1 else
                tags.li(tags.span(html.raw("Next &raquo;"))),
            )
        )

def folder_page (folder, cur_page) :
    """
        Render the per-Folder view for the given page
    """

    # render the paginate-view once
    paginate = folder_paginate(folder, cur_page)

    return [
        # title
        tags.h1(folder.title) if folder.title else None,

        # subdirs
        tags.div(id='dirs')(
            tags.ul(
                tags.li(
                    folder_link(folder, subfolder)
                ) for subfolder in folder.subfolders
            ) if folder.subfolders else None
        ),

        # upper paginate
        paginate,

        # image thumbnails
        tags.div(id='thumbnails')(
            image_link(folder, image.thumb, image.html) for image in folder.images_for_page(cur_page)
        ),

        # lower paginate
        paginate,

        # description
        tags.p(id='description')(folder.description) if folder.description else None,

        # shorturl
    ]

def breadcrumb_trail (gallery, cur_page) :
    """
        Yield the breadcrumb elements
    """

    is_first = True
    
    for page in gallery.path_to(cur_page) :
        # spacers
        if is_first :
            is_first = False

        else :
            yield html.raw("&raquo;")

        # link from this page to sub-page
        yield link_from(cur_page, page.html)(page.title)

def breadcrumb (gallery, page) :
    """
        Build a breadcrumb trail from the gallery root to the given object
    """

    return tags.div(id='breadcrumb')(
        breadcrumb_trail(gallery, page)
    )

def master (gallery, page, body) :
    """
        Render the full-page HTML layout for the given page with title and body
    """

    return html.XHTMLDocument(
        head=[
            tags.title(page.title),
            
            # stylesheet
            tags.link(rel='Stylesheet', type='text/css', href=gallery.stylesheet.path_from(page.html))
        ],

        body=[
            # top-of-page breadcrumb nav
            breadcrumb(gallery, page),
            
            # other content
            body,
            
            # footer
            tags.p(id='about')(
                "Generated using",
                tags.a(href='http://projects.qmsk.net/degal')('Degal'), 
                "version",
                tags.a(href=version.VERSION_URL)(version.VERSION_STRING),
            )
        ],
    )