degal/templates.py
author Tero Marttila <terom@fixme.fi>
Fri, 03 Jul 2009 00:00:51 +0300
changeset 147 283a15412709
parent 143 a6e53a20fccb
permissions -rw-r--r--
remove obsolete shorturl.py
"""
    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,
        ),

        # metadata
        tags.div(id='metadata')(*(
            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='footer')(page.config.footer),
        ],
    )

# default footer used
footer = (
    "Generated using",
    tags.a(href='http://projects.qmsk.net/degal')('Degal'), 
    "version",
    tags.a(href=version.VERSION_URL)(version.VERSION_STRING),
)