def get_admin_log(parser, token): """ Populates a template variable with the admin log for the given criteria. Usage:: {% get_admin_log [limit] as [varname] for_user [context_var_containing_user_obj] %} Examples:: {% get_admin_log 10 as admin_log for_user 23 %} {% get_admin_log 10 as admin_log for_user user %} {% get_admin_log 10 as admin_log %} Note that ``context_var_containing_user_obj`` can be a hard-coded integer (user ID) or the name of a template context variable containing the user object whose ID you want. """ tokens = token.contents.split() if len(tokens) < 4: raise template.TemplateSyntaxError( "'get_admin_log' statements require two arguments") if not tokens[1].isdigit(): raise template.TemplateSyntaxError( "First argument to 'get_admin_log' must be an integer") if tokens[2] != 'as': raise template.TemplateSyntaxError( "Second argument to 'get_admin_log' must be 'as'") if len(tokens) > 4: if tokens[4] != 'for_user': raise template.TemplateSyntaxError( "Fourth argument to 'get_admin_log' must be 'for_user'") return AdminLogNode(limit=tokens[1], varname=tokens[3], user=(len(tokens) > 5 and tokens[5] or None))
def handle_token(cls, parser, token): """Class method to parse get_comment_list/count/form and return a Node.""" tokens = token.contents.split() if tokens[1] != 'for': raise template.TemplateSyntaxError( "Second argument in %r tag must be 'for'" % tokens[0]) # {% get_whatever for obj as varname %} if len(tokens) == 5: if tokens[3] != 'as': raise template.TemplateSyntaxError( "Third argument in %r must be 'as'" % tokens[0]) return cls( object_expr=parser.compile_filter(tokens[2]), as_varname=tokens[4], ) # {% get_whatever for app.model pk as varname %} elif len(tokens) == 6: if tokens[4] != 'as': raise template.TemplateSyntaxError( "Fourth argument in %r must be 'as'" % tokens[0]) return cls(ctype=BaseCommentNode.lookup_content_type( tokens[2], tokens[0]), object_pk_expr=parser.compile_filter(tokens[3]), as_varname=tokens[5]) else: raise template.TemplateSyntaxError( "%r tag requires 4 or 5 arguments" % tokens[0])
def get_flatpages(parser, token): """ Retrieves all flatpage objects available for the current site and visible to the specific user (or visible to all users if no user is specified). Populates the template context with them in a variable whose name is defined by the ``as`` clause. An optional ``for`` clause can be used to control the user whose permissions are to be used in determining which flatpages are visible. An optional argument, ``starts_with``, can be applied to limit the returned flatpages to those beginning with a particular base URL. This argument can be passed as a variable or a string, as it resolves from the template context. Syntax:: {% get_flatpages ['url_starts_with'] [for user] as context_name %} Example usage:: {% get_flatpages as flatpages %} {% get_flatpages for someuser as flatpages %} {% get_flatpages '/about/' as about_pages %} {% get_flatpages prefix as about_pages %} {% get_flatpages '/about/' for someuser as about_pages %} """ bits = token.split_contents() syntax_message = ("%(tag_name)s expects a syntax of %(tag_name)s " "['url_starts_with'] [for user] as context_name" % dict(tag_name=bits[0])) # Must have at 3-6 bits in the tag if len(bits) >= 3 and len(bits) <= 6: # If there's an even number of bits, there's no prefix if len(bits) % 2 == 0: prefix = bits[1] else: prefix = None # The very last bit must be the context name if bits[-2] != 'as': raise template.TemplateSyntaxError(syntax_message) context_name = bits[-1] # If there are 5 or 6 bits, there is a user defined if len(bits) >= 5: if bits[-4] != 'for': raise template.TemplateSyntaxError(syntax_message) user = bits[-3] else: user = None return FlatpageNode(context_name, starts_with=prefix, user=user) else: raise template.TemplateSyntaxError(syntax_message)
def lookup_content_type(token, tagname): try: app, model = token.split('.') return ContentType.objects.get_by_natural_key(app, model) except ValueError: raise template.TemplateSyntaxError( "Third argument in %r must be in the format 'app.model'" % tagname) except ContentType.DoesNotExist: raise template.TemplateSyntaxError( "%r tag has non-existant content-type: '%s.%s'" % (tagname, app, model))
def handle_token(cls, parser, token, name): """ Class method to parse prefix node and return a Node. """ tokens = token.contents.split() if len(tokens) > 1 and tokens[1] != 'as': raise template.TemplateSyntaxError( "First argument in '%s' must be 'as'" % tokens[0]) if len(tokens) > 1: varname = tokens[2] else: varname = None return cls(varname, name)
def textile(value): try: import textile except ImportError: if settings.DEBUG: raise template.TemplateSyntaxError( "Error in 'textile' filter: The Python textile library isn't installed." ) return force_unicode(value) else: return mark_safe( force_unicode( textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, comment=None): if ctype is None and object_expr is None: raise template.TemplateSyntaxError( "Comment nodes must be given either a literal object or a ctype and object pk." ) self.comment_model = comments.get_model() self.as_varname = as_varname self.ctype = ctype self.object_pk_expr = object_pk_expr self.object_expr = object_expr self.comment = comment
def handle_token(cls, parser, token): """Class method to parse render_comment_list and return a Node.""" tokens = token.contents.split() if tokens[1] != 'for': raise template.TemplateSyntaxError( "Second argument in %r tag must be 'for'" % tokens[0]) # {% render_comment_list for obj %} if len(tokens) == 3: return cls(object_expr=parser.compile_filter(tokens[2])) # {% render_comment_list for app.models pk %} elif len(tokens) == 4: return cls(ctype=BaseCommentNode.lookup_content_type( tokens[2], tokens[0]), object_pk_expr=parser.compile_filter(tokens[3]))
def restructuredtext(value): try: from docutils.core import publish_parts except ImportError: if settings.DEBUG: raise template.TemplateSyntaxError( "Error in 'restructuredtext' filter: The Python docutils library isn't installed." ) return force_unicode(value) else: docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings) return mark_safe(force_unicode(parts["fragment"]))
def lorem(parser, token): """ Creates random Latin text useful for providing test data in templates. Usage format:: {% lorem [count] [method] [random] %} ``count`` is a number (or variable) containing the number of paragraphs or words to generate (default is 1). ``method`` is either ``w`` for words, ``p`` for HTML paragraphs, ``b`` for plain-text paragraph blocks (default is ``b``). ``random`` is the word ``random``, which if given, does not use the common paragraph (starting "Lorem ipsum dolor sit amet, consectetuer..."). Examples: * ``{% lorem %}`` will output the common "lorem ipsum" paragraph * ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph and two random paragraphs each wrapped in HTML ``<p>`` tags * ``{% lorem 2 w random %}`` will output two random latin words """ bits = list(token.split_contents()) tagname = bits[0] # Random bit common = bits[-1] != 'random' if not common: bits.pop() # Method bit if bits[-1] in ('w', 'p', 'b'): method = bits.pop() else: method = 'b' # Count bit if len(bits) > 1: count = bits.pop() else: count = '1' count = parser.compile_filter(count) if len(bits) != 1: raise template.TemplateSyntaxError("Incorrect format for %r tag" % tagname) return LoremNode(count, method, common)
def markdown(value, arg=''): """ Runs Markdown over a given value, optionally using various extensions python-markdown supports. Syntax:: {{ value|markdown:"extension1_name,extension2_name..." }} To enable safe mode, which strips raw HTML and only returns HTML generated by actual Markdown syntax, pass "safe" as the first extension in the list. If the version of Markdown in use does not support extensions, they will be silently ignored. """ try: import markdown except ImportError: if settings.DEBUG: raise template.TemplateSyntaxError( "Error in 'markdown' filter: The Python markdown library isn't installed." ) return force_unicode(value) else: # markdown.version was first added in 1.6b. The only version of markdown # to fully support extensions before 1.6b was the shortlived 1.6a. if hasattr(markdown, 'version'): extensions = [e for e in arg.split(",") if e] if len(extensions) > 0 and extensions[0] == "safe": extensions = extensions[1:] safe_mode = True else: safe_mode = False python_markdown_deprecation = "The use of Python-Markdown " "< 2.1 in Django is deprecated; please update to the current version" # Unicode support only in markdown v1.7 or above. Version_info # exist only in markdown v1.6.2rc-2 or above. markdown_vers = getattr(markdown, "version_info", None) if markdown_vers < (1, 7): warnings.warn(python_markdown_deprecation, DeprecationWarning) return mark_safe( force_unicode( markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode))) else: if markdown_vers >= (2, 1): if safe_mode: return mark_safe( markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode, enable_attributes=False)) else: return mark_safe( markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode)) else: warnings.warn(python_markdown_deprecation, DeprecationWarning) return mark_safe( markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode)) else: warnings.warn(python_markdown_deprecation, DeprecationWarning) return mark_safe(force_unicode(markdown.markdown( smart_str(value))))
def __init__(self, varname=None, name=None): if name is None: raise template.TemplateSyntaxError( "Prefix nodes must be given a name to return.") self.varname = varname self.name = name