/pages/utils.py
Python | 139 lines | 99 code | 14 blank | 26 comment | 26 complexity | fc8315bd3755dfbaae347213f617c6d7 MD5 | raw file
- # -*- coding: utf-8 -*-
- """A collection of functions for Page CMS"""
- from pages import settings
- from pages.http import get_request_mock
- from django.template import TemplateDoesNotExist
- from django.template import loader, Context, RequestContext
- from django.core.cache import cache
- import re
- def get_context_mock():
- """return a mockup dictionnary to use in get_placeholders."""
- context = {'current_page':None}
- if settings.PAGE_EXTRA_CONTEXT:
- context.update(settings.PAGE_EXTRA_CONTEXT())
- return context
- def get_placeholders(template_name):
- """Return a list of PlaceholderNode found in the given template.
- :param template_name: the name of the template file
- """
- try:
- temp = loader.get_template(template_name)
- except TemplateDoesNotExist:
- return []
-
- request = get_request_mock()
- context = get_context_mock()
- # I need to render the template in order to extract
- # placeholder tags
- temp.render(RequestContext(request, context))
- plist, blist = [], []
- _placeholders_recursif(temp.nodelist, plist, blist)
- return plist
- def _placeholders_recursif(nodelist, plist, blist):
- """Recursively search into a template node list for PlaceholderNode
- node."""
- # I needed to import make this lazy import to make the doc compile
- from django.template.loader_tags import BlockNode
-
- for node in nodelist:
- # extends node
- if hasattr(node, 'parent_name'):
- _placeholders_recursif(node.get_parent(Context()).nodelist,
- plist, blist)
- # include node
- elif hasattr(node, 'template'):
- _placeholders_recursif(node.template.nodelist, plist, blist)
- # It's a placeholder
- if hasattr(node, 'page') and hasattr(node, 'parsed') and \
- hasattr(node, 'as_varname') and hasattr(node, 'name'):
- already_in_plist = False
- for placeholder in plist:
- if placeholder.name == node.name:
- already_in_plist = True
- if not already_in_plist:
- if len(blist):
- node.found_in_block = blist[len(blist)-1]
- plist.append(node)
- node.render(Context())
- for key in ('nodelist', 'nodelist_true', 'nodelist_false'):
- if isinstance(node, BlockNode):
- # delete placeholders found in a block of the same name
- for index, pl in enumerate(plist):
- if pl.found_in_block and \
- pl.found_in_block.name == node.name \
- and pl.found_in_block != node:
- del plist[index]
- blist.append(node)
-
- if hasattr(node, key):
- try:
- _placeholders_recursif(getattr(node, key), plist, blist)
- except:
- pass
- if isinstance(node, BlockNode):
- blist.pop()
- def normalize_url(url):
- """Return a normalized url with trailing and without leading slash.
-
- >>> normalize_url(None)
- '/'
- >>> normalize_url('/')
- '/'
- >>> normalize_url('/foo/bar')
- '/foo/bar'
- >>> normalize_url('foo/bar')
- '/foo/bar'
- >>> normalize_url('/foo/bar/')
- '/foo/bar'
- """
- if not url or len(url)==0:
- return '/'
- if not url.startswith('/'):
- url = '/' + url
- if len(url)>1 and url.endswith('/'):
- url = url[0:len(url)-1]
- return url
- PAGE_CLASS_ID_REGEX = re.compile('page_([0-9]+)')
- def filter_link(content, page, language, content_type):
- """Transform the HTML link href to point to the targeted page
- absolute URL.
- >>> filter_link('<a class="page_1">hello</a>', page, 'en-us', body)
- '<a href="/pages/page-1" class="page_1">hello</a>'
- """
- if not settings.PAGE_LINK_FILTER:
- return content
- if content_type in ('title', 'slug'):
- return content
- from BeautifulSoup import BeautifulSoup
- tree = BeautifulSoup(content)
- tags = tree.findAll('a')
- if len(tags) == 0:
- return content
- for tag in tags:
- tag_class = tag.get('class', False)
- if tag_class:
- # find page link with class 'page_ID'
- result = PAGE_CLASS_ID_REGEX.search(content)
- if result and result.group:
- try:
- # TODO: try the cache before fetching the Page object
- from pages.models import Page
- target_page = Page.objects.get(pk=int(result.group(1)))
- tag['href'] = target_page.get_url_path(language)
- except Page.DoesNotExist:
- cache.set(Page.PAGE_BROKEN_LINK_KEY % page.id, True)
- tag['class'] = 'pagelink_broken'
- return unicode(tree)