PageRenderTime 75ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/pages/utils.py

https://github.com/Gautier/django-page-cms
Python | 139 lines | 99 code | 14 blank | 26 comment | 26 complexity | fc8315bd3755dfbaae347213f617c6d7 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. """A collection of functions for Page CMS"""
  3. from pages import settings
  4. from pages.http import get_request_mock
  5. from django.template import TemplateDoesNotExist
  6. from django.template import loader, Context, RequestContext
  7. from django.core.cache import cache
  8. import re
  9. def get_context_mock():
  10. """return a mockup dictionnary to use in get_placeholders."""
  11. context = {'current_page':None}
  12. if settings.PAGE_EXTRA_CONTEXT:
  13. context.update(settings.PAGE_EXTRA_CONTEXT())
  14. return context
  15. def get_placeholders(template_name):
  16. """Return a list of PlaceholderNode found in the given template.
  17. :param template_name: the name of the template file
  18. """
  19. try:
  20. temp = loader.get_template(template_name)
  21. except TemplateDoesNotExist:
  22. return []
  23. request = get_request_mock()
  24. context = get_context_mock()
  25. # I need to render the template in order to extract
  26. # placeholder tags
  27. temp.render(RequestContext(request, context))
  28. plist, blist = [], []
  29. _placeholders_recursif(temp.nodelist, plist, blist)
  30. return plist
  31. def _placeholders_recursif(nodelist, plist, blist):
  32. """Recursively search into a template node list for PlaceholderNode
  33. node."""
  34. # I needed to import make this lazy import to make the doc compile
  35. from django.template.loader_tags import BlockNode
  36. for node in nodelist:
  37. # extends node
  38. if hasattr(node, 'parent_name'):
  39. _placeholders_recursif(node.get_parent(Context()).nodelist,
  40. plist, blist)
  41. # include node
  42. elif hasattr(node, 'template'):
  43. _placeholders_recursif(node.template.nodelist, plist, blist)
  44. # It's a placeholder
  45. if hasattr(node, 'page') and hasattr(node, 'parsed') and \
  46. hasattr(node, 'as_varname') and hasattr(node, 'name'):
  47. already_in_plist = False
  48. for placeholder in plist:
  49. if placeholder.name == node.name:
  50. already_in_plist = True
  51. if not already_in_plist:
  52. if len(blist):
  53. node.found_in_block = blist[len(blist)-1]
  54. plist.append(node)
  55. node.render(Context())
  56. for key in ('nodelist', 'nodelist_true', 'nodelist_false'):
  57. if isinstance(node, BlockNode):
  58. # delete placeholders found in a block of the same name
  59. for index, pl in enumerate(plist):
  60. if pl.found_in_block and \
  61. pl.found_in_block.name == node.name \
  62. and pl.found_in_block != node:
  63. del plist[index]
  64. blist.append(node)
  65. if hasattr(node, key):
  66. try:
  67. _placeholders_recursif(getattr(node, key), plist, blist)
  68. except:
  69. pass
  70. if isinstance(node, BlockNode):
  71. blist.pop()
  72. def normalize_url(url):
  73. """Return a normalized url with trailing and without leading slash.
  74. >>> normalize_url(None)
  75. '/'
  76. >>> normalize_url('/')
  77. '/'
  78. >>> normalize_url('/foo/bar')
  79. '/foo/bar'
  80. >>> normalize_url('foo/bar')
  81. '/foo/bar'
  82. >>> normalize_url('/foo/bar/')
  83. '/foo/bar'
  84. """
  85. if not url or len(url)==0:
  86. return '/'
  87. if not url.startswith('/'):
  88. url = '/' + url
  89. if len(url)>1 and url.endswith('/'):
  90. url = url[0:len(url)-1]
  91. return url
  92. PAGE_CLASS_ID_REGEX = re.compile('page_([0-9]+)')
  93. def filter_link(content, page, language, content_type):
  94. """Transform the HTML link href to point to the targeted page
  95. absolute URL.
  96. >>> filter_link('<a class="page_1">hello</a>', page, 'en-us', body)
  97. '<a href="/pages/page-1" class="page_1">hello</a>'
  98. """
  99. if not settings.PAGE_LINK_FILTER:
  100. return content
  101. if content_type in ('title', 'slug'):
  102. return content
  103. from BeautifulSoup import BeautifulSoup
  104. tree = BeautifulSoup(content)
  105. tags = tree.findAll('a')
  106. if len(tags) == 0:
  107. return content
  108. for tag in tags:
  109. tag_class = tag.get('class', False)
  110. if tag_class:
  111. # find page link with class 'page_ID'
  112. result = PAGE_CLASS_ID_REGEX.search(content)
  113. if result and result.group:
  114. try:
  115. # TODO: try the cache before fetching the Page object
  116. from pages.models import Page
  117. target_page = Page.objects.get(pk=int(result.group(1)))
  118. tag['href'] = target_page.get_url_path(language)
  119. except Page.DoesNotExist:
  120. cache.set(Page.PAGE_BROKEN_LINK_KEY % page.id, True)
  121. tag['class'] = 'pagelink_broken'
  122. return unicode(tree)