Latest Version: 0.9.6.2
/Users/bbangert/Programming/Python/WebHelpers/webhelpers/rails/asset_tag.py
0001"""
0002Asset Tag Helpers
0003
0004Provides functionality for linking an HTML page together with other assets, such as
0005images, javascripts, stylesheets, and feeds.
0006"""
0007# Last synced with Rails copy at Revision 6057 on Feb 7th, 2007.
0008
0009import os
0010import re
0011import urlparse
0012import warnings
0013from tags import *
0014from routes import request_config
0015
0016# The absolute path of the WebHelpers javascripts directory
0017javascript_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
0018                               'javascripts')
0019
0020# WebHelpers' built-in javascripts. Note: scriptaculous automatically includes all of its
0021# supporting .js files
0022javascript_builtins = ('prototype.js', 'scriptaculous.js')
0023
0024def auto_discovery_link_tag(source, type='rss', **kwargs):
0025    """
0026    Returns a link tag allowing browsers and news readers (that support it) to auto-detect
0027    an RSS or ATOM feed for current page.
0028
0029    ``source``
0030        The URL of the feed. The URL is ultimately prepended with the environment's
0031        ``SCRIPT_NAME`` (the root path of the web application), unless the URL is
0032        fully-fledged (e.g. http://example.com).
0033
0034    ``type``
0035        The type of feed. Specifying 'rss' or 'atom' automatically translates to a type of
0036        'application/rss+xml' or 'application/atom+xml', respectively. Otherwise the type
0037        is used as specified. Defaults to 'rss'.
0038        
0039    Examples::
0040
0041        >>> auto_discovery_link_tag('http://feed.com/feed.xml')
0042        '<link href="http://feed.com/feed.xml" rel="alternate" title="RSS" type="application/rss+xml" />'
0043
0044        >>> auto_discovery_link_tag('http://feed.com/feed.xml', type='atom')
0045        '<link href="http://feed.com/feed.xml" rel="alternate" title="ATOM" type="application/atom+xml" />'
0046
0047        >>> auto_discovery_link_tag('app.rss', type='atom', title='atom feed')
0048        '<link href="app.rss" rel="alternate" title="atom feed" type="application/atom+xml" />'
0049
0050        >>> auto_discovery_link_tag('/app.html', type='text/html')
0051        '<link href="/app.html" rel="alternate" title="" type="text/html" />'
0052    """
0053    title = ''
0054    if type.lower() in ('rss', 'atom'):
0055        title = type.upper()
0056        type = 'application/%s+xml' % type.lower()
0057
0058    tag_args = dict(rel='alternate', type=type, title=title,
0059                    href=compute_public_path(source))
0060    kwargs.pop('href', None)
0061    kwargs.pop('type', None)
0062    tag_args.update(kwargs)
0063    return tag('link', **tag_args)
0064
0065def image_tag(source, alt=None, size=None, **options):
0066    """
0067    Returns an image tag for the specified ``source``.
0068
0069    ``source``
0070        The source URL of the image. The URL is prepended with '/images/', unless its full
0071        path is specified. The URL is ultimately prepended with the environment's
0072        ``SCRIPT_NAME`` (the root path of the web application), unless the URL is
0073        fully-fledged (e.g. http://example.com).
0074    
0075    ``alt``
0076        The img's alt tag. Defaults to the source's filename, title cased.
0077
0078    ``size``
0079        The img's size, specified in the format "XxY". "30x45" becomes
0080        width="30", height="45". "x20" becomes height="20".
0081        
0082    Examples::
0083
0084        >>> image_tag('xml.png')
0085        '<img alt="Xml" src="/images/xml.png" />'
0086
0087        >>> image_tag('rss.png', 'rss syndication')
0088        '<img alt="rss syndication" src="/images/rss.png" />'
0089
0090        >>> image_tag("icon.png", size="16x10", alt="Edit Entry")
0091        '<img alt="Edit Entry" height="10" src="/images/icon.png" width="16" />'
0092
0093        >>> image_tag("/icons/icon.gif", size="16x16")
0094        '<img alt="Icon" height="16" src="/icons/icon.gif" width="16" />'
0095
0096        >>> image_tag("/icons/icon.gif", size="16x")
0097        '<img alt="Icon" src="/icons/icon.gif" width="16" />'
0098    """
0099    if not os.path.splitext(source)[1]:
0100        warnings.warn("You've called image_tag with a source that doesn't include an "
0101                      "extension. Soon image_tag will no longer automatically append "
0102                      "'.png' to your source. Please call image_path('%s.png') "
0103                      "instead." % source, DeprecationWarning, 2)
0104    options['src'] = compute_public_path(source, 'images', 'png')
0105
0106    if not alt:
0107        alt = os.path.splitext(os.path.basename(source))[0].title()
0108    options['alt'] = alt
0109
0110    if size and re.match('^(\d+|)x(\d+|)$', size) and size != 'x':
0111        width, height = size.split('x')
0112        if width:
0113            options['width'] = width
0114        if height:
0115            options['height'] = height
0116
0117    return tag('img', **options)
0118
0119def javascript_include_tag(*sources, **options):
0120    """
0121    Returns script include tags for the specified javascript ``sources``.
0122
0123    Each source's URL path is prepended with '/javascripts/' unless their full path is
0124    specified. Each source's URL path is ultimately prepended with the environment's
0125    ``SCRIPT_NAME`` (the root path of the web application), unless the URL path is a
0126    full-fledged URL (e.g. http://example.com). Sources with no filename extension will be
0127    appended with the '.js' extension.
0128
0129    Optionally includes (prepended) WebHelpers' built-in javascripts when passed the
0130    ``builtins=True`` keyword argument.
0131
0132    Specify the keyword argument ``defer=True`` to enable the script defer attribute.
0133
0134    Examples::
0135    
0136        >>> print javascript_include_tag(builtins=True)
0137        <script src="/javascripts/prototype.js" type="text/javascript"></script>
0138        <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
0139
0140        >>> print javascript_include_tag(builtins=True, defer=True)
0141        <script defer="defer" src="/javascripts/prototype.js" type="text/javascript"></script>
0142        <script defer="defer" src="/javascripts/scriptaculous.js" type="text/javascript"></script>
0143
0144        >>> print javascript_include_tag('prototype', '/other-javascripts/util.js')
0145        <script src="/javascripts/prototype.js" type="text/javascript"></script>
0146        <script src="/other-javascripts/util.js" type="text/javascript"></script>
0147
0148        >>> print javascript_include_tag('app', '/test/test.1.js', builtins=True)
0149        <script src="/javascripts/prototype.js" type="text/javascript"></script>
0150        <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
0151        <script src="/javascripts/app.js" type="text/javascript"></script>
0152        <script src="/test/test.1.js" type="text/javascript"></script>
0153    """
0154    if options.pop('builtins', False):
0155        sources = javascript_builtins + sources
0156    if options.get('defer') == True:
0157        options['defer'] = 'defer'
0158
0159    tags = []
0160    for source in sources:
0161        content_options = dict(type='text/javascript',
0162                               src=compute_public_path(source, 'javascripts',
0163                                                       'js'))
0164        content_options.update(options)
0165        tags.append(content_tag('script', None, **content_options))
0166    return '\n'.join(tags)
0167
0168def stylesheet_link_tag(*sources, **options):
0169    """
0170    Returns CSS link tags for the specified stylesheet ``sources``.
0171
0172    Each source's URL path is prepended with '/stylesheets/' unless their full path is
0173    specified. Each source's URL path is ultimately prepended with the environment's
0174    ``SCRIPT_NAME`` (the root path of the web application), unless the URL path is a
0175    full-fledged URL (e.g. http://example.com). Sources with no filename extension will be
0176    appended with the '.css' extension.
0177    
0178    Examples::
0179
0180        >>> stylesheet_link_tag('style')
0181        '<link href="/stylesheets/style.css" media="screen" rel="Stylesheet" type="text/css" />'
0182
0183        >>> stylesheet_link_tag('dir/file', media='all')
0184        '<link href="/stylesheets/dir/file.css" media="all" rel="Stylesheet" type="text/css" />'
0185
0186        >>> stylesheet_link_tag('/dir/file', media='all')
0187        '<link href="/dir/file.css" media="all" rel="Stylesheet" type="text/css" />'
0188    """
0189    tag_options = dict(rel='Stylesheet', type='text/css', media='screen')
0190    tag_options.update(options)
0191    tag_options.pop('href', None)
0192
0193    tags = [tag('link', **dict(href=compute_public_path(source, 'stylesheets', 'css'),
0194                               **tag_options)) for source in sources]
0195    return '\n'.join(tags)
0196
0197def compute_public_path(source, root_path=None, ext=None):
0198    """
0199    Format the specified source for publishing, via the public directory, if applicable.
0200    """
0201    if ext and not os.path.splitext(os.path.basename(source))[1]:
0202        source = '%s.%s' % (source, ext)
0203
0204    # Avoid munging fully-fledged URLs, including 'mailto:'
0205    parsed = urlparse.urlparse(source)
0206    if not (parsed[0] and (parsed[1] or parsed[2])):
0207        # Prefix apps deployed under any SCRIPT_NAME path
0208        if not root_path or source.startswith('/'):
0209            source = '%s%s' % (get_script_name(), source)
0210        else:
0211            source = '%s/%s/%s' % (get_script_name(), root_path, source)
0212    return source
0213
0214def get_script_name():
0215    """
0216    Determine the current web application's ``SCRIPT_NAME``.
0217    """
0218    script_name = ''
0219    config = request_config()
0220    if hasattr(config, 'environ'):
0221        script_name = config.environ.get('SCRIPT_NAME', '')
0222    return script_name
0223
0224__all__ = ['javascript_path', 'javascript_builtins', 'auto_discovery_link_tag',
0225           'image_tag', 'javascript_include_tag', 'stylesheet_link_tag']

Top