def include_block(parser, token): """ Render the passed item of StreamField content, passing the current template context if there's an identifiable way of doing so (i.e. if it has a `render_as_block` method). """ tokens = token.split_contents() try: tag_name = tokens.pop(0) block_var_token = tokens.pop(0) except IndexError: raise template.TemplateSyntaxError("%r tag requires at least one argument" % tag_name) block_var = parser.compile_filter(block_var_token) if tokens and tokens[0] == 'with': tokens.pop(0) extra_context = token_kwargs(tokens, parser) else: extra_context = None use_parent_context = True if tokens and tokens[0] == 'only': tokens.pop(0) use_parent_context = False if tokens: raise template.TemplateSyntaxError("Unexpected argument to %r tag: %r" % (tag_name, tokens[0])) return IncludeBlockNode(block_var, extra_context, use_parent_context)
def include_block(parser, token): """ Render the passed item of StreamField content, passing the current template context if there's an identifiable way of doing so (i.e. if it has a `render_as_block` method). """ tokens = token.split_contents() try: tag_name = tokens.pop(0) block_var_token = tokens.pop(0) except IndexError: raise template.TemplateSyntaxError( "%r tag requires at least one argument" % tag_name) block_var = parser.compile_filter(block_var_token) if tokens and tokens[0] == 'with': tokens.pop(0) extra_context = token_kwargs(tokens, parser) else: extra_context = None use_parent_context = True if tokens and tokens[0] == 'only': tokens.pop(0) use_parent_context = False if tokens: raise template.TemplateSyntaxError( "Unexpected argument to %r tag: %r" % (tag_name, tokens[0])) return IncludeBlockNode(block_var, extra_context, use_parent_context)
def do_render_model(parser, token): bits = token.split_contents() if len(bits) < 3: raise TemplateSyntaxError("%r tag takes at least two arguments: the object and the name of the template to render it with." % bits[0]) options = {} remaining_bits = bits[3:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=False) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'only': value = True else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value isolated_context = options.get('only', False) namemap = options.get('with', {}) return RenderObjectNode( parser.compile_filter(bits[1]), parser.compile_filter(bits[2]), extra_context=namemap, isolated_context=isolated_context)
def __render_helper(parser, token): tokens = token.split_contents() try: tag_name = tokens.pop(0) block_var_token = tokens.pop(0) except IndexError: raise template.TemplateSyntaxError( "%r tag requires at least one argument" % tag_name) block_var = parser.compile_filter(block_var_token) if tokens and tokens[0] == 'with': tokens.pop(0) extra_context = token_kwargs(tokens, parser) else: extra_context = None use_parent_context = True if tokens and tokens[0] == 'only': tokens.pop(0) use_parent_context = False if tokens: raise template.TemplateSyntaxError( "Unexpected argument to %r tag: %r" % (tag_name, tokens[0])) return HyperNode(block_var, extra_context, use_parent_context)
def signed_amount(parser, token): """Take a number and currency and display it according to the language Examples: {% signed_amount 100 'USD' %} Shows 100$ in russian and $100 in other languages {% signed_amount -100 'EUR' %} Shows -100€ in russian language and -€100 in other languages It also accepts precision argument, and rounds the value to that precision with decimal computations {% signed_amount balance account.currency precision=2 %} """ bits = token.split_contents() if not 3 <= len(bits) <= 4: raise template.TemplateSyntaxError, "%r tag requires 2 arguments" % token.contents.split( )[0] tag, amount, currency = bits[:3] extra_context = token_kwargs(bits[3:], parser) amount = template.Variable(amount) currency = template.Variable(currency) return SignedAmountNode(amount, currency, extra_context=extra_context)
def provider_login_url(parser, token): """ """ bits = token.split_contents() provider_id = bits[1] params = token_kwargs(bits[2:], parser, support_legacy=False) return ProviderLoginURLNode(provider_id, params)
def get_settings(parser, token): bits = token.split_contents()[1:] target_var = "settings" if len(bits) >= 2 and bits[-2] == "as": target_var = bits[-1] bits = bits[:-2] kwargs = token_kwargs(bits, parser) if bits else {} return GetSettingsNode(kwargs, target_var)
def provider_login_url(parser, token): """ {% provider_login_url "facebook" next=bla %} {% provider_login_url "openid" openid="http://me.yahoo.com" next=bla %} """ bits = token.split_contents() provider_id = bits[1] params = token_kwargs(bits[2:], parser, support_legacy=False) return ProviderLoginURLNode(provider_id, params)
def get_url(parser, token): bits = token.split_contents() remaining_bits = bits[1:] extra_context = token_kwargs(remaining_bits, parser, support_legacy=True) if not extra_context: raise TemplateSyntaxError("%r expected at least one variable assignment" % bits[0]) if remaining_bits: raise TemplateSyntaxError("%r received an invalid token: %r" % (bits[0], remaining_bits[0])) return get_url_node(extra_context)
def do_section_menu(parser, token): try: # split_contents() knows not to split quoted strings. args = token.split_contents()[1:] kwargs = token_kwargs(args, parser) if len(args) > 0: raise ValueError except ValueError: raise djtemplate.TemplateSyntaxError( "%r tag accepts only keyword arguments" \ % token.contents.split()[0]) return SectionMenuNode(**kwargs)
def do_category_menu(parser, token): try: # split_contents() knows not to split quoted strings. args = token.split_contents()[1:] kwargs = token_kwargs(args, parser) if len(args) > 0: raise ValueError except ValueError: raise djtemplate.TemplateSyntaxError( "%r tag accepts only keyword arguments" \ % token.contents.split()[0]) return CategoryMenuNode(**kwargs)
def canjs(parser, token): bits = token.split_contents() if len(bits) > 1: kwargs = token_kwargs(bits[1:], parser, support_legacy=False) for k,v in kwargs.iteritems(): if isinstance(v, FilterExpression): v = str(v.var) if k == "extras": v = v.split(",") kwargs[k] = v urls = canjs_urls(**kwargs) else: urls = canjs_urls() return CanJSNode(urls=urls)
def do_include(parser, token): """ Loads a template and renders it with the current context. You can pass additional context using keyword arguments. Example:: {% include "foo/some_include" %} {% include "foo/some_include" with bar="BAZZ!" baz="BING!" %} Use the ``only`` argument to exclude the current context when rendering the included template:: {% include "foo/some_include" only %} {% include "foo/some_include" with bar="1" only %} """ bits = token.split_contents() if len(bits) < 2: raise TemplateSyntaxError( "%r tag takes at least one argument: the name of the template to be included." % bits[0]) options = {} remaining_bits = bits[2:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=False) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'only': value = True else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value isolated_context = options.get('only', False) namemap = options.get('with', {}) path = bits[1] if path[0] in ('"', "'") and path[-1] == path[0]: return ConstantIncludeNode(path[1:-1], extra_context=namemap, isolated_context=isolated_context) return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap, isolated_context=isolated_context)
def _parse_blocks(cls, parser, token): """ Return an :class:`OrderedDict` of tag blocks as found in the template. Each block will be defined as: keyword: (processor, arguments, kwargs, body) """ blocks = OrderedDict() # Process first block block_arguments = token.split_contents() block_keyword = block_arguments.pop(0) processors = cls._get_declared_blocks() closing_keyword = 'end_' + block_keyword while (True): try: block_processor = processors[block_keyword] except KeyError: raise TemplateSyntaxError( 'Block %r not found, candidates are %r' % (block_keyword, block_processor._next_blocks)) # Parse token keyword arguments if necessary if cls.resolve_block_parameters: # The parsed keyword arguments are removed from the original # list block_kwargs = token_kwargs(block_arguments, parser) else: block_kwargs = {} # Parse the body of the block next_blocks = _MultiBlockTagPrefixes(block_processor._next_blocks) block_body = parser.parse(next_blocks) blocks[block_keyword] = ((block_processor, block_arguments, block_kwargs, block_body)) # Parse next block token = parser.next_token() block_arguments = token.split_contents() block_keyword = block_arguments.pop(0) if block_keyword == closing_keyword: break return blocks
def _parse_blocks(cls, parser, token): """ Return an :class:`OrderedDict` of tag blocks as found in the template. Each block will be defined as: keyword: (processor, arguments, kwargs, body) """ blocks = OrderedDict() # Process first block block_arguments = token.split_contents() block_keyword = block_arguments.pop(0) processors = cls._get_declared_blocks() closing_keyword = "end_" + block_keyword while True: try: block_processor = processors[block_keyword] except KeyError: raise TemplateSyntaxError( "Block %r not found, candidates are %r" % (block_keyword, block_processor._next_blocks) ) # Parse token keyword arguments if necessary if cls.resolve_block_parameters: # The parsed keyword arguments are removed from the original # list block_kwargs = token_kwargs(block_arguments, parser) else: block_kwargs = {} # Parse the body of the block next_blocks = _MultiBlockTagPrefixes(block_processor._next_blocks) block_body = parser.parse(next_blocks) blocks[block_keyword] = (block_processor, block_arguments, block_kwargs, block_body) # Parse next block token = parser.next_token() block_arguments = token.split_contents() block_keyword = block_arguments.pop(0) if block_keyword == closing_keyword: break return blocks
def do_include(parser, token): """ Loads a template and renders it with the current context. You can pass additional context using keyword arguments. Example:: {% include "foo/some_include" %} {% include "foo/some_include" with bar="BAZZ!" baz="BING!" %} Use the ``only`` argument to exclude the current context when rendering the included template:: {% include "foo/some_include" only %} {% include "foo/some_include" with bar="1" only %} """ bits = token.split_contents() if len(bits) < 2: raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0]) options = {} remaining_bits = bits[2:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=False) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'only': value = True else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value isolated_context = options.get('only', False) namemap = options.get('with', {}) path = bits[1] if path[0] in ('"', "'") and path[-1] == path[0]: return ConstantIncludeNode(path[1:-1], extra_context=namemap, isolated_context=isolated_context) return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap, isolated_context=isolated_context)
def payment_details(parser, token): """ Outputs HTML code needed to render details of a payment. """ token_parts = token.split_contents() if len(token_parts) < 2: raise TemplateSyntaxError("A payment detail dictionary is a mandatory parameter for %r" % token_parts[0]) payment_info_reference = token_parts[1] remaining_token_parts = token_parts[2:] options = token_kwargs(remaining_token_parts, parser, support_legacy = False) if remaining_token_parts: raise TemplateSyntaxError("%r received an invalid token: %r" % \ (token_parts[0], remaining_token_parts[0])) for (key, value) in options.items(): options[key] = unicode(value) return PaymentDetailsNode(payment_info_reference, options)
def payment_details(parser, token): """ Outputs HTML code needed to render details of a payment. """ token_parts = token.split_contents() if len(token_parts) < 2: raise TemplateSyntaxError( "A payment detail dictionary is a mandatory parameter for %r" % token_parts[0]) payment_info_reference = token_parts[1] remaining_token_parts = token_parts[2:] options = token_kwargs(remaining_token_parts, parser, support_legacy=False) if remaining_token_parts: raise TemplateSyntaxError("%r received an invalid token: %r" % \ (token_parts[0], remaining_token_parts[0])) for (key, value) in options.items(): options[key] = unicode(value) return PaymentDetailsNode(payment_info_reference, options)
def partial_include(parser, token): bits = token.split_contents() if len(bits) < 2: raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0]) options = {} remaining_bits = bits[2:] while remaining_bits: option = remaining_bits.pop(0) if option == "with": value = token_kwargs(remaining_bits, parser, support_legacy=False) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least one keyword argument.' % bits[0]) elif option == "only": value = True elif option == "quiet": value = True else: raise TemplateSyntaxError("Unknown argument for %r tag: %r." % (bits[0], option)) options[str(option)] = value options.setdefault("only", False) options.setdefault("quiet", False) options.setdefault("with", {}) block = options["with"].pop("block", None) if block: block = block.token if is_quoted(block): block = block[1:-1] template_name = bits[1] if is_quoted(template_name): resolve = False template_name = template_name[1:-1] else: resolve = True template_name = parser.compile_filter(template_name) return IncludeNode(template_name, resolve=resolve, block=block, **options)
def def_model_details(parser, token): params = token.split_contents() tag_name = params[0] if len(params) < 2: raise template.TemplateSyntaxError("{0} tag should have at least one argument") model = params[1] bits = params[2:] kwargs = token_kwargs(bits, parser) include_fields = kwargs.get('fields', None) exclude_fields = kwargs.get('exclude_fields', None) nodelist = parser.parse(("end" + tag_name, 'extra')) token = parser.next_token() if token.contents == 'extra': nodelist_extra = parser.parse(('end' + tag_name,)) parser.delete_first_token() else: nodelist_extra = None return ModelDetailsNode( model, nodelist, include_fields=include_fields, exclude_fields=exclude_fields, extra=nodelist_extra )
def make_tag(parser, token): nodelist = parser.parse(('endtag',)) parser.delete_first_token() tokens = token.split_contents() try: tag_name = tokens[1] except IndexError: raise TemplateSyntaxError( "'{}' tag requires at least 1 argument.".format(tokens[0])) if tag_name[0] != tag_name[-1] or tag_name[0] not in ['"', "'"]: raise TemplateSyntaxError( "'{}' tag's first argument should be in quotes.".format(tokens[0])) tag_name = tag_name[1:-1] options = {} remaining_bits = tokens[2:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError( "The '{}' option was specified more than once.".format(option)) if option == 'with': value = token_kwargs(remaining_bits, parser) if not value: raise TemplateSyntaxError( "'with' in '{}' tag needs at least one " "keyword argument.".format(tokens[0])) else: raise TemplateSyntaxError( "Unknown argument for '{}' tag: {}".format(tokens[0], option)) options[option] = value extra_context = options.get('with', {}) return TagNode(nodelist, tag_name, extra_context)
def _parse_block(self, token, parser, original_string): """Parse any {% ... %} token and return a migration object. :param django.template.base.Token token: the token object :param django.template.base.parser: the parser object :param unicode original_string: the string found in the template """ # Split the given token into its parts (includes the template tag # name), e.g. "{% trans "This is the title" context "Some context" %}" # returns: ['trans', '"This is the title"', 'context', '"Some # context"'] bits = token.split_contents() tag_name = bits[0] # Right after {% load i18n %} append a {% load transifex %} tag if (tag_name == templates.LOAD_TAG and bits[1] == templates.DJANGO_i18n_TAG_NAME): # Make sure there is not already a tag that loads "transifex" # by checking all remaining nodes for t in parser.tokens: if (templates.LOAD_TAG in t.contents and templates.TRANSIFEX_TAG_NAME in t.contents): return (StringMigration(original_string, original_string), None) string_migration = StringMigration( original_string, 'original\n{% load transifex %}'.replace( 'original', original_string), ) return string_migration, None # A {% with %} tag was found elif tag_name == templates.WITH_TAG: with_kwargs = token_kwargs(bits[1:], parser, support_legacy=True) self._with_kwargs.append( {k: v.var for k, v in with_kwargs.items()}) # An {% endwith %} tag was found elif tag_name == templates.ENDWITH_TAG: self._with_kwargs.pop() # A {% comment %} tag was found; If this is a translation comment, # expect the actual comment text to follow shortly elif tag_name == templates.COMMENT_TAG: next_token = parser.tokens[0] if parser.tokens else None if next_token.token_type == TOKEN_TEXT: comment = _retrieve_comment(next_token.contents) if comment: self._comment = COMMENT_FOUND # Create a string migration and start keeping track # of all the strings that will be migrated # within the following set of tokens that apply self._current_string_migration = StringMigration( original_string, '') return None, None # An {% endcomment %} tag was found elif tag_name == templates.ENDCOMMENT_TAG: # No need to do anything special, just make sure to record # that the tag is removed from the migrated result # If a translation comment wasn't open, ignore it if self._comment is not None: if self._current_string_migration: self._current_string_migration.update(original_string, '') return None, None # A {% trans %} tag was found elif tag_name in templates.TRANSLATE_TAGS: return self._parse_trans(token, parser, original_string) # A {% blocktrans %} tag was found elif tag_name in templates.BLOCK_TRANSLATE_TAGS: return self._parse_blocktrans(token, parser, original_string) # This is the default case; any other block tag that wasn't # explicitly covered above, which means that it doesn't need migration return StringMigration(original_string, original_string), None
def twitter_login_url(parser, token): bits = token.split_contents() params = token_kwargs(bits[1:], parser, support_legacy=False) return TwitterLoginURLNode(params)
def facebook_login_url(parser, token): bits = token.split_contents() params = token_kwargs(bits[1:], parser, support_legacy=False) return FacebookLoginURLNode(params)
def do_t(parser, token): """ Parse a transifex translation tag. Inline syntax: {% t/ut <source>[|filter...] [key=param[|filter...]...] [as <var>] %} <source> can either be a literal string or a variable containing a string. In each case, the string will be considered an ICU template whose parameters will be rendered against the parameters of the tag and the context of the template. Block syntax: {% t/ut [|filter...] [key=param[|filter...]...] [as <var>] %} <source> {% endt/ut %} <source> can be anything. Django template tokens will not be parsed, but captured verbatim (which will most likely mess up with ICU formatting). Arguments: :param parser: A django Parser object. Has information about how the templating engine is setup, what filters and tags are available and the tokens that haven't yet been processed :param token: A django Token instance. Has information about the contents of the token we are currently processing """ # We will gradually "consume" bits left-to-right. At any given moment, the # leftmost bit is the one we need to be processing bits = list(token.split_contents()) # {% t ... %} # ^ tag_name = bits.pop(0) # not {% t %} has_args = bool(bits) # {% t |escapejs ... %} ... {% endt %} first_arg_is_filter = has_args and bits[0].startswith('|') # {% t "hello world" ... %} first_arg_is_string_literal = (has_args and bits[0][0] in ('"', "'") and bits[0][0] == bits[0][-1]) # {% t var=var ... %} first_arg_is_param = (has_args and not first_arg_is_string_literal and '=' in bits[0]) # {% t as text %} first_arg_is_as = has_args and bits[0] == "as" is_block = (not has_args or first_arg_is_filter or first_arg_is_param or first_arg_is_as) if not is_block: # Treat the source string as a full filter expression. Proper # exceptions will be raised if it is not formatted properly source_string = parser.compile_filter(bits.pop(0)) else: block = [] while True: try: # `next_token` removes the first token from the parser's list token = parser.next_token() except IndexError: # We ran out of tokens raise TemplateSyntaxError( "'{tag_name}' tag not closed with " "'end{tag_name}'".format(tag_name=tag_name)) if (token.token_type == TOKEN_BLOCK and token.contents == "end{}".format(tag_name)): break # Here we capture the contents of the block verbatim. # Unfortunately, there is some loss of information here: When # django captures a token, it saves the content as # `text[2:-2].strip()`, which means that the size of the # surrounding spaces is lost. This means that we end up capturing # `{% tag%}` as `{% tag %}` if token.token_type == TOKEN_VAR: block.append(''.join((VARIABLE_TAG_START, ' ', token.contents, ' ', VARIABLE_TAG_END))) elif token.token_type == TOKEN_BLOCK: block.append(''.join((BLOCK_TAG_START, ' ', token.contents, ' ', BLOCK_TAG_END))) elif token.token_type == TOKEN_COMMENT and token.contents: block.append(''.join((COMMENT_TAG_START, ' ', token.contents, ' ', COMMENT_TAG_END))) elif token.token_type == TOKEN_TEXT: block.append(token.contents) else: # pragma: no cover # Unreachable code raise TemplateSyntaxError("Could not parse body of '{}' tag " "block".format(tag_name)) block = ''.join(block) # Create a dummy filter expression with the provided filters and then # replace its 'var' attribute with the captured text. This effectively # makes # `{% t %}text{% endt %}` equivalent to `{% t "text" %}` and # `{% t |filter %}text{% endt %}` equivalent to `{% t "text"|filter %}` # while allowing the text to contain characters that would be invalid # with the inline syntax, like newlines and `"` if first_arg_is_filter: source_string = parser.compile_filter('""' + bits.pop(0)) else: source_string = parser.compile_filter('""') source_string.var = block # {% t "string" var=value var2=value2 ... %} # ^^^^^^^^^ params_list = [] while bits and '=' in bits[0]: params_list.append(bits.pop(0)) # Proper exceptions will be raised if the params are not formatted properly params = token_kwargs(params_list, parser, support_legacy=False) # {% t "string" as var %} # ^^^^^^ asvar = None if bits: if len(bits) != 2 or bits[0] != "as": raise TemplateSyntaxError("Unrecognized tail: {}".format( ' '.join(bits))) else: asvar = bits[1] del bits[:2] if bits: raise TemplateSyntaxError("Unrecognized tail: {}".format( ' '.join(bits))) return TNode(tag_name, source_string, params, asvar)
def do_block_translate(parser, token): """ This will translate a block of text with parameters. Usage:: {% blocktrans with bar=foo|filter boo=baz|filter %} This is {{ bar }} and {{ boo }}. {% endblocktrans %} Additionally, this supports pluralization:: {% blocktrans count count=var|length %} There is {{ count }} object. {% plural %} There are {{ count }} objects. {% endblocktrans %} This is much like ngettext, only in template syntax. The "var as value" legacy format is still supported:: {% blocktrans with foo|filter as bar and baz|filter as boo %} {% blocktrans count var|length as count %} """ bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly ' 'one keyword argument.' % bits[0]) else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = options['count'].items()[0] else: countervar, counter = None, None extra_context = options.get('with', {}) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != 'endblocktrans': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) return BlockTranslateNode(extra_context, singular, plural, countervar, counter)
def get_flatpages(parser, token): """ Returns a list of flatpages based on the given criteria. Basic usage:: {% get_flatpages %} ... which returns all flatpages (not recommended on sites with many flatpages). Example usage:: {% get_flatpages as flatpages %} {% get_flatpages sort='views' as flatpages %} {% get_flatpages sort='random' limit=10 as random_flatpages %} {% get_flatpages owners=1 limit=5 as user_flatpages %} {% get_flatpages tags='foo,bar,baz' as flatpages %} {% get_flatpages starts_with='/about/' as about_pages %} {% get_flatpages sort='random' remove=flatpage.id limit=5 as random_flatpages %} All fields are optional. If nothing is passed to the templatetag, it will return all flatpages, sorted by most recently created Here are the available options:: sort= What to sort the flatpages by. Optional. Default is by url. 'created' Returns least recently created flatpages first. '-created' Returns most recently created flatpages first. 'modified' Returns least recently modified flatpages first. '-modified' Returns most recently modified flatpages first. 'views' Returns the most viewed flatpages first. '-views' Returns the least viewed flatpages first. 'random' Returns random flatpages. tags='foo,bar,baz' Returns all flatpages tagged with _either_ 'foo', 'bar', or 'baz'. Optional. not_tags='foo,bar' Removes any flatpages tagged with 'foo' or 'bar' from the QuerySet. starts_with='/about/' Return all flatpages that have a URL that starts with '/about/'. owners=1 Returns all flatpages by the User with ID 1. Optional. Can be a string of IDs (e.g. '1,5,6,8,234') or an integer (e.g. 1). Optional. limit=10 Limits the number of flatpages that are returned to 10 results. Optional. remove=1 Removes a given flatpage ID or list of IDs from the results list. Can be a string of IDs (e.g. '1,5,6,8,234') or an integer (e.g. 1). Optional. """ bits = token.split_contents() remaining_bits = bits[1:] var_name = 'flatpages' if remaining_bits: if remaining_bits[-2] == 'as': var_name = remaining_bits[-1] # Remove the var_name and "as" bits from the list or it will throw an error. del remaining_bits[-2:-1] extra_context = token_kwargs(remaining_bits, parser) return FlatpagesNode(extra_context, var_name)
def do_block_translate(parser, token): bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError( 'The %r option was specified more than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError( '"with" in %r tag needs at least one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError( '"count" in %r tag expected exactly one keyword argument.' % bits[0]) elif option == "context": try: value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: msg = ('"context" in %r tag expected exactly one argument.' ) % bits[0] six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = list(six.iteritems(options['count']))[0] else: countervar, counter = None, None if 'context' in options: message_context = options['context'] else: message_context = None extra_context = options.get('with', {}) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != 'endblocktrans': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) if phrase_settings.PHRASE_ENABLED: node = PhraseBlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context) else: node = BlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context) return node
from __future__ import unicode_literals
def do_block_translate(parser, token): """ This will translate a block of text with parameters. Usage:: {% blocktrans with bar=foo|filter boo=baz|filter %} This is {{ bar }} and {{ boo }}. {% endblocktrans %} Additionally, this supports pluralization:: {% blocktrans count count=var|length %} There is {{ count }} object. {% plural %} There are {{ count }} objects. {% endblocktrans %} This is much like ngettext, only in template syntax. The "var as value" legacy format is still supported:: {% blocktrans with foo|filter as bar and baz|filter as boo %} {% blocktrans count var|length as count %} Contextual translations are supported:: {% blocktrans with bar=foo|filter context "greeting" %} This is {{ bar }}. {% endblocktrans %} This is equivalent to calling pgettext/npgettext instead of (u)gettext/(u)ngettext. """ bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly ' 'one keyword argument.' % bits[0]) elif option == "context": try: value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: msg = ( '"context" in %r tag expected ' 'exactly one argument.') % bits[0] six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) elif option == "trimmed": value = True else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = list(six.iteritems(options['count']))[0] else: countervar, counter = None, None if 'context' in options: message_context = options['context'] else: message_context = None extra_context = options.get('with', {}) trimmed = options.get("trimmed", False) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != 'endblocktrans': raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) return BlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context, trimmed=trimmed)
def get_flatpages(parser, token): """ Returns a list of flatpages based on the given criteria. Basic usage:: {% get_flatpages %} ... which returns all flatpages (not recommended on sites with many flatpages). Example usage:: {% get_flatpages as flatpages %} {% get_flatpages sort='views' as flatpages %} {% get_flatpages sort='random' limit=10 as random_flatpages %} {% get_flatpages owners=1 limit=5 as user_flatpages %} {% get_flatpages tags='foo,bar,baz' as flatpages %} {% get_flatpages starts_with='/about/' as about_pages %} {% get_flatpages sort='random' remove=flatpage.id limit=5 as random_flatpages %} All fields are optional. If nothing is passed to the templatetag, it will return all flatpages, sorted by most recently created Here are the available options:: sort= What to sort the flatpages by. Optional. Default is by url. 'created' Returns least recently created flatpages first. '-created' Returns most recently created flatpages first. 'modified' Returns least recently modified flatpages first. '-modified' Returns most recently modified flatpages first. 'views' Returns the most viewed flatpages first. '-views' Returns the least viewed flatpages first. 'random' Returns random flatpages. tags='foo,bar,baz' Returns all flatpages tagged with _either_ 'foo', 'bar', or 'baz'. Optional. not_tags='foo,bar' Removes any flatpages tagged with 'foo' or 'bar' from the QuerySet. starts_with='/about/' Return all flatpages that have a URL that starts with '/about/'. owners=1 Returns all flatpages by the User with ID 1. Optional. Can be a string of IDs (e.g. '1,5,6,8,234') or an integer (e.g. 1). Optional. limit=10 Limits the number of flatpages that are returned to 10 results. Optional. remove=1 Removes a given flatpage ID or list of IDs from the results list. Can be a string of IDs (e.g. '1,5,6,8,234') or an integer (e.g. 1). Optional. """ bits = token.split_contents() remaining_bits = bits[1:] var_name = "flatpages" if remaining_bits: if remaining_bits[-2] == "as": var_name = remaining_bits[-1] # Remove the var_name and "as" bits from the list or it will throw an error. del remaining_bits[-2:-1] extra_context = token_kwargs(remaining_bits, parser) return FlatpagesNode(extra_context, var_name)
def do_block_translate(parser, token): """ Translate a block of text with parameters. Usage:: {% blocktranslate with bar=foo|filter boo=baz|filter %} This is {{ bar }} and {{ boo }}. {% endblocktranslate %} Additionally, this supports pluralization:: {% blocktranslate count count=var|length %} There is {{ count }} object. {% plural %} There are {{ count }} objects. {% endblocktranslate %} This is much like ngettext, only in template syntax. The "var as value" legacy format is still supported:: {% blocktranslate with foo|filter as bar and baz|filter as boo %} {% blocktranslate count var|length as count %} The translated string can be stored in a variable using `asvar`:: {% blocktranslate with bar=foo|filter boo=baz|filter asvar var %} This is {{ bar }} and {{ boo }}. {% endblocktranslate %} {{ var }} Contextual translations are supported:: {% blocktranslate with bar=foo|filter context "greeting" %} This is {{ bar }}. {% endblocktranslate %} This is equivalent to calling pgettext/npgettext instead of (u)gettext/(u)ngettext. """ bits = token.split_contents() options = {} remaining_bits = bits[1:] asvar = None while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly ' 'one keyword argument.' % bits[0]) elif option == "context": try: value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: raise TemplateSyntaxError( '"context" in %r tag expected exactly one argument.' % bits[0]) elif option == "trimmed": value = True elif option == "asvar": try: value = remaining_bits.pop(0) except IndexError: raise TemplateSyntaxError( "No argument provided to the '%s' tag for the asvar option." % bits[0]) asvar = value else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = next(iter(options['count'].items())) else: countervar, counter = None, None if 'context' in options: message_context = options['context'] else: message_context = None extra_context = options.get('with', {}) trimmed = options.get("trimmed", False) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TokenType.VAR, TokenType.TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError( "%r doesn't allow other block tags inside it" % bits[0]) while parser.tokens: token = parser.next_token() if token.token_type in (TokenType.VAR, TokenType.TEXT): plural.append(token) else: break end_tag_name = 'end%s' % bits[0] if token.contents.strip() != end_tag_name: raise TemplateSyntaxError( "%r doesn't allow other block tags (seen %r) inside it" % (bits[0], token.contents)) return BlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context, trimmed=trimmed, asvar=asvar, tag_name=bits[0])
def do_block_translate(parser, token): bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError("The %r option was specified more than once." % option) if option == "with": value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least one keyword argument.' % bits[0]) elif option == "count": value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly one keyword argument.' % bits[0]) elif option == "context": try: value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: msg = ('"context" in %r tag expected exactly one argument.') % bits[0] six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) else: raise TemplateSyntaxError("Unknown argument for %r tag: %r." % (bits[0], option)) options[option] = value if "count" in options: countervar, counter = list(six.iteritems(options["count"]))[0] else: countervar, counter = None, None if "context" in options: message_context = options["context"] else: message_context = None extra_context = options.get("with", {}) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != "plural": raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != "endblocktrans": raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) if phrase_settings.PHRASE_ENABLED: node = PhraseBlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context) else: node = BlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context) return node
def openid_login_url(parser, token): bits = token.split_contents() params = token_kwargs(bits[1:], parser, support_legacy=False) return OpenIDLoginURLNode(params)
def do_block_translate(parser, token): """ This will translate a block of text with parameters. Usage:: {% blocktrans with bar=foo|filter boo=baz|filter %} This is {{ bar }} and {{ boo }}. {% endblocktrans %} Additionally, this supports pluralization:: {% blocktrans count count=var|length %} There is {{ count }} object. {% plural %} There are {{ count }} objects. {% endblocktrans %} This is much like ngettext, only in template syntax. The "var as value" legacy format is still supported:: {% blocktrans with foo|filter as bar and baz|filter as boo %} {% blocktrans count var|length as count %} """ bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly ' 'one keyword argument.' % bits[0]) else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = options['count'].items()[0] else: countervar, counter = None, None extra_context = options.get('with', {}) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != 'endblocktrans': raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) return BlockTranslateNode(extra_context, singular, plural, countervar, counter)
def do_block_translate(parser, token): """ This will translate a block of text with parameters. Usage:: {% blocktrans with bar=foo|filter boo=baz|filter %} This is {{ bar }} and {{ boo }}. {% endblocktrans %} Additionally, this supports pluralization:: {% blocktrans count count=var|length %} There is {{ count }} object. {% plural %} There are {{ count }} objects. {% endblocktrans %} This is much like ngettext, only in template syntax. The "var as value" legacy format is still supported:: {% blocktrans with foo|filter as bar and baz|filter as boo %} {% blocktrans count var|length as count %} Contextual translations are supported:: {% blocktrans with bar=foo|filter context "greeting" %} This is {{ bar }}. {% endblocktrans %} This is equivalent to calling pgettext/npgettext instead of (u)gettext/(u)ngettext. """ bits = token.split_contents() options = {} remaining_bits = bits[1:] while remaining_bits: option = remaining_bits.pop(0) if option in options: raise TemplateSyntaxError('The %r option was specified more ' 'than once.' % option) if option == 'with': value = token_kwargs(remaining_bits, parser, support_legacy=True) if not value: raise TemplateSyntaxError('"with" in %r tag needs at least ' 'one keyword argument.' % bits[0]) elif option == 'count': value = token_kwargs(remaining_bits, parser, support_legacy=True) if len(value) != 1: raise TemplateSyntaxError('"count" in %r tag expected exactly ' 'one keyword argument.' % bits[0]) elif option == "context": try: value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: msg = ('"context" in %r tag expected ' 'exactly one argument.') % bits[0] six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) elif option == "trimmed": value = True else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % (bits[0], option)) options[option] = value if 'count' in options: countervar, counter = list(six.iteritems(options['count']))[0] else: countervar, counter = None, None if 'context' in options: message_context = options['context'] else: message_context = None extra_context = options.get('with', {}) trimmed = options.get("trimmed", False) singular = [] plural = [] while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): singular.append(token) else: break if countervar and counter: if token.contents.strip() != 'plural': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags inside it") while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): plural.append(token) else: break if token.contents.strip() != 'endblocktrans': raise TemplateSyntaxError( "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents) return BlockTranslateNode(extra_context, singular, plural, countervar, counter, message_context, trimmed=trimmed)