示例#1
0
class StaticPlaceholderNode(Tag):
    name = 'static_placeholder'
    options = PlaceholderOptions(Argument('code', required=True),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endstatic_placeholder', 'nodelist'),
                                 ])

    def render_tag(self, context, code, extra_bits, nodelist=None):
        # TODO: language override (the reason this is not implemented, is that language selection is buried way
        #       down somewhere in some method called in render_plugins. There it gets extracted from the request
        #       and a language in request.GET always overrides everything.)
        if not code:
            # an empty string was passed in or the variable is not available in the context
            if nodelist:
                return nodelist.render(context)
            return ''
        request = context.get('request', False)
        if not request:
            if nodelist:
                return nodelist.render(context)
            return ''
        if isinstance(code, StaticPlaceholder):
            static_placeholder = code
        else:
            if 'site' in extra_bits:
                site = Site.objects.get_current()
                static_placeholder, __ = StaticPlaceholder.objects.get_or_create(
                    code=code,
                    site_id=site.pk,
                    defaults={
                        'name': code,
                        'creation_method':
                        StaticPlaceholder.CREATION_BY_TEMPLATE
                    })
            else:
                static_placeholder, __ = StaticPlaceholder.objects.get_or_create(
                    code=code,
                    site_id__isnull=True,
                    defaults={
                        'name': code,
                        'creation_method':
                        StaticPlaceholder.CREATION_BY_TEMPLATE
                    })
        if not hasattr(request, 'static_placeholders'):
            request.static_placeholders = []
        request.static_placeholders.append(static_placeholder)
        if hasattr(request, 'toolbar') and request.toolbar.edit_mode:
            placeholder = static_placeholder.draft
        else:
            placeholder = static_placeholder.public
        placeholder.is_static = True
        content = render_placeholder(placeholder,
                                     context,
                                     name_fallback=code,
                                     default=nodelist)
        return content
示例#2
0
class Placeholder(Tag):
    """
    This template node is used to output page content and
    is also used in the admin to dynamically generate input fields.

    eg: {% placeholder "placeholder_name" %}

    {% placeholder "sidebar" inherit %}

    {% placeholder "footer" inherit or %}
        <a href="/about/">About us</a>
    {% endplaceholder %}

    Keyword arguments:
    name -- the name of the placeholder
    inherit -- optional argument which if given will result in inheriting
        the content of the placeholder with the same name on parent pages
    or -- optional argument which if given will make the template tag a block
        tag whose content is shown if the placeholder is empty
    """
    name = 'placeholder'
    options = PlaceholderOptions(
        Argument('name', resolve=False),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        blocks=[
            ('endplaceholder', 'nodelist'),
        ],
    )

    def render_tag(self, context, name, extra_bits, nodelist=None):
        validate_placeholder_name(name)

        content_renderer = context.get('cms_content_renderer')

        if not content_renderer:
            return ''

        inherit = 'inherit' in extra_bits
        content = content_renderer.render_page_placeholder(
            slot=name,
            context=context,
            inherit=inherit,
            nodelist=nodelist,
        )
        return content

    def get_name(self):
        return self.kwargs['name'].var.value.strip('"').strip("'")

    def get_inherit_status(self):
        flags = self.kwargs['extra_bits']

        if not isinstance(flags, ListValue):
            return False

        for extra in self.kwargs['extra_bits']:
            if extra.var.value.strip() == 'inherit':
                return True
        return False
示例#3
0
class Placeholder(Tag):
    """
    This template node is used to output page content and
    is also used in the admin to dynamically generate input fields.

    eg: {% placeholder "placeholder_name" %}

    {% placeholder "sidebar" inherit %}

    {% placeholder "footer" inherit or %}
        <a href="/about/">About us</a>
    {% endplaceholder %}

    Keyword arguments:
    name -- the name of the placeholder
    inherit -- optional argument which if given will result in inheriting
        the content of the placeholder with the same name on parent pages
    or -- optional argument which if given will make the template tag a block
        tag whose content is shown if the placeholder is empty
    """
    name = 'placeholder'
    options = PlaceholderOptions(Argument('name', resolve=False),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endplaceholder', 'nodelist'),
                                 ])

    def render_tag(self, context, name, extra_bits, nodelist=None):
        validate_placeholder_name(name)
        inherit = False
        for bit in extra_bits:
            if bit == 'inherit':
                inherit = True
        if not 'request' in context:
            return ''
        request = context['request']
        page = request.current_page
        if not page or page == 'dummy':
            if nodelist:
                return nodelist.render(context)
            return ''
        content = ''
        try:
            content = get_placeholder_content(context, request, page, name,
                                              inherit, nodelist)
        except PlaceholderNotFound:
            if nodelist:
                return nodelist.render(context)
        if not content:
            if nodelist:
                return nodelist.render(context)
            return ''
        return content

    def get_name(self):
        return self.kwargs['name'].var.value.strip('"').strip("'")
    def handle_as_arg(self, value, kwargs):
        if self.name in kwargs:
            if self.max_values and len(kwargs[self.name]) == self.max_values:
                return False
            kwargs[self.name].append(value)
        else:
            kwargs[self.name] = MultiValueArgument.sequence_class(value)

        return True
示例#5
0
class ArticlePlaceholder(Tag):
    """
    This template node is used to output article content and
    is also used in the admin to dynamically generate input fields.

    eg: {% article_placeholder "placeholder_name" %}

    {% article_placeholder "footer" or %}
        <a href="/about/">About us</a>
    {% endarticle_placeholder %}

    Keyword arguments:
    name -- the name of the placeholder
    or -- optional argument which if given will make the template tag a block
        tag whose content is shown if the placeholder is empty
    """
    name = 'article_placeholder'
    options = PlaceholderOptions(
        Argument('name', resolve=False),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        blocks=[
            ('endarticle_placeholder', 'nodelist'),
        ],
    )

    def render_tag(self, context, name, extra_bits, nodelist=None):
        request = context.get('request')

        if not request:
            return ''

        validate_placeholder_name(name)

        toolbar = get_toolbar_from_request(request)
        renderer = toolbar.get_content_renderer()
        inherit = False

        try:
            content = renderer.render_page_placeholder(
                slot=name,
                context=context,
                inherit=inherit,
                page=request.current_article,
                nodelist=nodelist,
            )
        except PlaceholderNotFound:
            content = ''

        if not content and nodelist:
            return nodelist.render(context)
        return content

    def get_declaration(self):
        slot = self.kwargs['name'].var.value.strip('"').strip("'")

        return DeclaredPlaceholder(slot=slot, inherit=False)
示例#6
0
class StaticPlaceholderNode(Tag):
    name = 'static_placeholder'
    options = PlaceholderOptions(Argument('code', required=True),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endstatic_placeholder', 'nodelist'),
                                 ])

    def render_tag(self, context, code, extra_bits, nodelist=None):
        request = context.get('request')

        if not code or not request:
            # an empty string was passed in or the variable is not available in the context
            if nodelist:
                return nodelist.render(context)
            return ''

        toolbar = get_toolbar_from_request(request)
        renderer = toolbar.get_content_renderer()

        if isinstance(code, StaticPlaceholder):
            static_placeholder = code
        else:
            kwargs = {
                'code': code,
                'defaults': {
                    'creation_method': StaticPlaceholder.CREATION_BY_TEMPLATE
                }
            }

            if 'site' in extra_bits:
                kwargs['site'] = get_current_site()
            else:
                kwargs['site_id__isnull'] = True
            static_placeholder = StaticPlaceholder.objects.get_or_create(
                **kwargs)[0]

        content = renderer.render_static_placeholder(
            static_placeholder,
            context=context,
            nodelist=nodelist,
        )
        return content

    def get_declaration(self, context):
        flags = self.kwargs['extra_bits']
        slot = self.kwargs['code'].resolve(context)

        if isinstance(flags, ListValue):
            site_bound = any(extra.var.value.strip() == 'site'
                             for extra in flags)
            return DeclaredStaticPlaceholder(slot=slot, site_bound=site_bound)
        return DeclaredStaticPlaceholder(slot=slot, site_bound=False)
示例#7
0
class FieldsetTag(Tag):
    """
    FieldsetTag renders fieldset with specified fields in it.

    **Usage:** ::

        {% fieldset 'field1' 'field2' [title 'MyFieldset'] %}
        {% fieldset unused_fields %}
    """
    name = 'fieldset'
    options = Options(
        MultiValueArgument('fields'),
        'title',
        Argument('title', required=False),
    )
    template = 'zenforms/fieldset.html'

    def udpate_context(self, fields, form, tag_context, unused_fields):
        if type(fields) is list and fields[0] == unused_fields:
            # ``unused_fields`` is the argument
            iterable = tuple(unused_fields)
        else:
            iterable = fields
        for field in iterable:
            try:
                if type(field) in [SafeUnicode, str]:
                    tag_context['fields'].append(form[field])
                    unused_fields.remove(field)
                elif type(field) is MultiField:
                    tag_context['fields'].append(field)
                    for fname in field.field_names:
                        unused_fields.remove(fname)
                elif type(field) is ReadonlyField:
                    tag_context['fields'].append(field)
            except KeyError:
                raise TemplateError('form does not contain field %s' % field)

    def get_context(self, context, title, fields):
        tag_context = {'fields': [], 'title': title}
        try:
            form = context['form']
            unused_fields = context['unused_fields']
        except KeyError:
            raise TemplateError(
                'fieldset tag must be used in {% zenform %}{% endzenform %} context'
            )
        self.udpate_context(fields, form, tag_context, unused_fields)
        context.update(tag_context)
        return context

    def render_tag(self, context, title, fields):
        context = self.get_context(context, title, fields)
        template = loader.get_template(self.template)
        output = template.render(context)
        return output
class GetSlot(AsTag):
    name = 'get_slot'
    options = Options(
        MultiValueArgument('keys', required=False, resolve=True), 'as',
        Argument('varname', required=False, resolve=False, default="slot"))

    def get_value(self, context, keys):
        key = get_key(context, keys)

        slot, created = models.Slot.objects.get_or_create(key=key)

        return slot
示例#9
0
class Rule(AsTag):
    options = Options(
        Argument('rule_name'),
        MultiValueArgument('args', required=False),
        MultiKeywordArgument('kwargs', required=False),
        'as',
        Argument('varname', resolve=False, required=False),
    )

    def get_value(self, context, rule_name, args, kwargs):
        return rules_light.run(context['request'].user, rule_name, *args,
                               **kwargs)
示例#10
0
class GetPlaceholderPlugins(Tag):
    """
    A template tag that gets plugins from a page's placeholder and sets them as a context variable:

        {% get_placeholder_plugins "logo" page_lookup as varname %}
        {% get_placeholder_plugins "logo" page_lookup as varname or %}
            <div>No content</div>
        {% endget_placeholder_plugins %}

    The page_lookup parameter can be omitted and will default to the current page

        {% get_placeholder_plugins "logo" as varname %}
        {% get_placeholder_plugins "logo" as varname or %}
            <div>No content</div>
        {% endget_placeholder_plugins %}

    This tag can typically be used in association with the block_plugin tag,
    to render the retrieved plugins:

        {% get_placeholder_plugins "logo" page_lookup as plugins %}
        {% blockplugin plugins.0 %}
            <img src="{% thumbnail instance.picture 300x150 %}"/>
        {% endblockplugin %}

    Keyword arguments:
        name: the name of the placeholder
        page_lookup: lookup argument for Page. See `_get_page_by_untyped_arg()`
            for detailed information on the allowed types and their interpretation for the
            `page_lookup` argument.
        varname: context variable name. Output will be added to template context as this variable
            instead of being returned.
        or: optional argument which if given will make the template tag a block
            tag whose content is shown if the placeholder is empty
    """

    name = "get_placeholder_plugins"
    options = PlaceholderOptions(
        Argument("name", resolve=False),
        Argument("page_lookup", required=False, default=None),
        "as",
        Argument("varname", resolve=False),
        MultiValueArgument("extra_bits", required=False, resolve=False),
        blocks=[("endget_placeholder_plugins", "nodelist")],
    )

    # pylint: disable=arguments-differ,too-many-arguments, unused-argument
    def render_tag(
        self, context, name, page_lookup, varname, extra_bits, nodelist=None
    ):
        return get_plugins_render_tag(
            context, name, varname, nodelist, page_lookup, edit=False
        )
示例#11
0
class GetGrid(AsTag):
    name = 'get_grid'
    options = Options(
        MultiValueArgument('keys', required=False, resolve=False),
        'as',
        Argument('varname', required=False, resolve=False, default="grid")
    )

    def get_value(self, context, keys):
        key = get_key(context, keys)

        grid, created = models.Grid.objects.get_or_create(key=key)

        return grid
示例#12
0
class PlaceholderAttr(Tag):
    name = 'placeholder_attr'
    options = PlaceholderOptions(Argument('name', resolve=False),
                                 Argument('plugin_class_name', resolve=False),
                                 Argument('plugin_attr', resolve=False),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endplaceholder', 'nodelist'),
                                 ])

    def render_tag(self,
                   context,
                   name,
                   plugin_class_name,
                   plugin_attr,
                   extra_bits,
                   nodelist=None):
        validate_placeholder_name(name)
        width = None
        for bit in extra_bits:
            if bit == 'inherit':
                pass
            elif bit.isdigit():
                width = int(bit)
                import warnings

                warnings.warn(
                    "The width parameter for the placeholder " +
                    "tag is deprecated.", DeprecationWarning)
        if not 'request' in context:
            return ''
        request = context['request']
        if width:
            context.update({'width': width})

        page = request.current_page
        if not page or page == 'dummy':
            if nodelist:
                return nodelist.render(context)

            return ''

        placeholder = _get_placeholder(page, page, context, name)

        res = get_placholder_attr(placeholder, name, plugin_class_name,
                                  plugin_attr)

        return res
示例#13
0
class ReadonlyTag(Tag):
    name = 'readonly'
    template = 'zenforms/fields/readonly.html'
    options = Options(
        Argument('instance'),
        MultiValueArgument('fields'),
        'label',
        Argument('label', required=False, default=None),
        'as',
        Argument('varname', resolve=False, required=False, default=None),
    )

    def get_context(self, instance, field_names, label):
        opts = instance._meta
        context = {}
        fields = []
        for fname in field_names:
            try:
                f = opts.get_field_by_name(fname)[0]
            except FieldDoesNotExist:
                raise TemplateError('Field %s not exists in a model' % fname)
            else:
                fields.append({
                    'value': f.value_from_object(instance),
                    'meta': f
                })

        context['fields'] = fields
        if label:
            context['label'] = label
        else:
            context['label'] = fields[0]['meta'].verbose_name

        context['help_text'] = fields[0]['meta'].help_text
        return context

    def render_tag(self, context, instance, fields, label, varname):
        ctx = self.get_context(instance, fields, label)
        if varname:
            context[varname] = ReadonlyField(**ctx)
            return u''
        else:
            context.push()
            context.update({'readonly': ctx})
            template = loader.get_template(self.template)
            output = template.render(context)
            context.pop()
            return output
示例#14
0
class RenderSlot(InclusionTag):
    name = 'render_slot'
    template = 'slot/slot.html'
    options = Options(MultiValueArgument('keys', required=False,
                                         resolve=True), )

    def get_context(self, context, keys):
        if keys and isinstance(keys[0], models.Slot):
            slot = keys[0]

        else:
            key = get_key(context, keys)
            slot, created = models.Slot.objects.get_or_create(key=key)

        context.update({"slot": slot})

        return context
示例#15
0
class RenderGetPlaceholder(Placeholder):
    """
    Render the content of a placeholder to a variable. Can be provided
    with the name of the placholder (i.e. "Header" in the case of a normal
    CMS page) or a template variable containing a placeholder (i.e. myentry.content in the
    case of an external app using a placeholder)

    {% get_placeholder ["string"|placeholder_var] as variable_name %}
    
    e.g.
    {% load extra_cms_tags %}
    {% get_placeholder "My Placeholder" as my_placeholder %}

    {% if my_placeholder %}
    <div>
        {{ my_placeholder }}
    </div>
    {% endif %}
    """
    name = "get_placeholder"

    options = PlaceholderOptions(
        Argument('name', resolve=True),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        'as',
        Argument('varname', resolve=False, required=True),
        blocks=[
            ('endplaceholder', 'nodelist'),
        ],
    )

    def render_tag(self, context, name, extra_bits, varname, nodelist=None):
        if isinstance(name, PlaceholderModel):
            content = name.render(context, None)
        else:
            content = super(RenderGetPlaceholder,
                            self).render_tag(context, name, extra_bits,
                                             nodelist)
        context[varname] = mark_safe(content)
        return ""

    def get_name(self):
        # Fix some template voodoo causing errors
        if isinstance(self.kwargs['name'].var, StringValue):
            return self.kwargs['name'].var.value.strip('"').strip("'")
        return self.kwargs['name'].var.var
示例#16
0
class PlaceholderAsPlugins(Placeholder):
    """
    Like DjangoCMS 'placeholder' but sets the list of linked plugins to a variable name
    instead of rendering the placeholder.
    """

    name = "placeholder_as_plugins"
    options = PlaceholderOptions(
        Argument("name", resolve=False),
        "as",
        Argument("varname", resolve=False),
        MultiValueArgument("extra_bits", required=False, resolve=False),
        blocks=[("endplaceholder_as_plugins", "nodelist")],
    )

    # pylint: disable=arguments-renamed,too-many-arguments
    def render_tag(self, context, name, varname, extra_bits, nodelist=None):
        return get_plugins_render_tag(context, name, varname, nodelist)
示例#17
0
class StaticPlaceholderNode(Tag):
    name = 'static_placeholder'
    options = PlaceholderOptions(Argument('code', required=True),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endstatic_placeholder', 'nodelist'),
                                 ])

    def render_tag(self, context, code, extra_bits, nodelist=None):
        content_renderer = context.get('cms_content_renderer')

        if not code or not content_renderer:
            # an empty string was passed in or the variable is not available in the context
            # OR cms_content_renderer is missing from context
            if nodelist:
                return nodelist.render(context)
            return ''

        if isinstance(code, StaticPlaceholder):
            static_placeholder = code
        else:
            kwargs = {
                'code': code,
                'defaults': {
                    'creation_method': StaticPlaceholder.CREATION_BY_TEMPLATE
                }
            }

            if 'site' in extra_bits:
                kwargs['site'] = Site.objects.get_current()
            else:
                kwargs['site_id__isnull'] = True
            static_placeholder = StaticPlaceholder.objects.get_or_create(
                **kwargs)[0]

        content = content_renderer.render_static_placeholder(
            static_placeholder,
            context=context,
            nodelist=nodelist,
        )
        return content
示例#18
0
class RenderGrid(InclusionTag):
    name = 'render_grid'
    template = 'grid/grid.html'
    options = Options(
        MultiValueArgument('keys', required=False, resolve=True),
    )

    def get_context(self, context, keys):
        if keys and isinstance(keys[0], models.Grid):
            grid = keys[0]

        else:
            key = get_key(context, keys)
            grid, created = models.Grid.objects.get_or_create(key=key)

        context.update({
            "grid": grid})

        return context
示例#19
0
class FrontEditTag(Tag):
    name = 'front_edit'
    options = Options(
        Argument('name', resolve=False, required=True),
        MultiValueArgument('extra_bits', required=False, resolve=True),
        blocks=[('end_front_edit', 'nodelist')],
    )

    def render_tag(self, context, name, extra_bits, nodelist=None):
        hash_val = Placeholder.key_for(name, *extra_bits)
        cache_key = "front-edit-%s" % hash_val

        val = cache.get(cache_key)
        if val is None:
            try:
                val = Placeholder.objects.get(key=hash_val).value
                cache.set(cache_key, val, 3600 * 24)
            except Placeholder.DoesNotExist:
                pass

        if val is None and nodelist:
            val = nodelist.render(context)

        classes = ['editable']

        if getattr(django_front_settings,
                   'DJANGO_FRONT_EXTRA_CONTAINER_CLASSES', None):
            classes.append(
                six.text_type(django_front_settings.
                              DJANGO_FRONT_EXTRA_CONTAINER_CLASSES))

        user = context.get('request', None) and context.get('request').user
        if django_front_settings.DJANGO_FRONT_PERMISSION(user):
            render = six.text_type(smart_text(val)).strip()
            if not strip_tags(render).strip():
                classes.append('empty-editable')

            return '<div class="%s" id="%s">%s</div>' % (
                ' '.join(classes),
                hash_val,
                render,
            )
        return val or ''
示例#20
0
class GetPlaceholderPlugins(Placeholder):
    """
    A template tag that declares a placeholder and sets its plugins as a context variable
    instead of rendering them eg:

        {% get_placeholder_plugins "logo" as varname %}
        {% get_placeholder_plugins "logo" as varname or %}
            <div>No content</div>
        {% endget_placeholder_plugins %}

    This tag can typically be used in association with the block_plugin tag, to customize the
    way it is rendered eg:

        {% get_placeholder_plugins "logo" as plugins %}
        {% blockplugin plugins.0 %}
            <img src="{% thumbnail instance.picture 300x150 %}"/>
        {% endblockplugin %}

    Keyword arguments:
        name: the name of the placeholder
        varname: context variable name. Output will be added to template context as this variable
            instead of being returned.
        or: optional argument which if given will make the template tag a block
            tag whose content is shown if the placeholder is empty

    Note: We must derive from the Placeholder class so that the tag is recognized as a
          placeholder and shown in the structure toolbar.
    """

    name = "get_placeholder_plugins"
    options = PlaceholderOptions(
        Argument("name", resolve=False),
        "as",
        Argument("varname", resolve=False),
        MultiValueArgument("extra_bits", required=False, resolve=False),
        blocks=[("endget_placeholder_plugins", "nodelist")],
    )

    # pylint: disable=arguments-differ,too-many-arguments
    def render_tag(self, context, name, varname, extra_bits, nodelist=None):
        return get_plugins_render_tag(context, name, varname, nodelist)
示例#21
0
class GetParameters(Tag):
    """
    {% raw %}{% get_parameters [except_field, ] %}{% endraw %}
    """
    name = 'get_parameters'
    options = Options(MultiValueArgument('except_fields', required=False), )

    def render_tag(self, context, except_fields):
        try:
            # If there's an exception (500), default context_processors may not
            # be called.
            request = context['request']
        except KeyError:
            return context

        getvars = request.GET.copy()

        for field in except_fields:
            if field in getvars:
                del getvars[field]

        return getvars.urlencode()
示例#22
0
class RenderPlaceholder(Placeholder):
    """
    Render the content of a placeholder to a variable.

    {% placeholder "placeholder_name" as variable_name %}
    """
    name = "get_placeholder"

    options = PlaceholderOptions(
        Argument('name', resolve=False),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        'as',
        Argument('varname', resolve=False),
        blocks=[
            ('endplaceholder', 'nodelist'),
        ],
    )

    def render_tag(self, context, name, extra_bits, varname, nodelist=None):
        content = super(RenderPlaceholder,
                        self).render_tag(context, name, extra_bits, nodelist)
        context[varname] = mark_safe(content)
        return ""
示例#23
0
class Slot(InclusionTag):
    name = 'slot'
    template = 'slot/slot.html'
    options = Options(
#        MultiValueArgument("tagname"),
#        KeywordArgument("tagname", required=True, resolve=True),
        MultiValueArgument('keys', required=True, resolve=True),
#        blocks=[('endplaceholder_objects', 'nodelist', )],
    )

    def get_context(self, context, keys):
        parts = []
        for part in [k for k in keys if k]:
            if isinstance(part, Model):
                key = u"%s,%s,%d" % (
                    part._meta.app_label, part.__class__.__name__, part.pk)
            else:
                key = unicode(part)
            parts.append(key)

        key = u"|".join([unicode(i) for i in parts])
        slot, created = models.Slot.objects.get_or_create(key=key)
        return {"slot": slot}
示例#24
0
class PagePlaceholder(Placeholder):
    """
    This template node is used to output page content and
    is also used in the admin to dynamically generate input fields.
    eg:
    {% page_placeholder "sidebar" page_lookup %}
    {% page_placeholder "sidebar" page_lookup inherit %}
    {% page_placeholder "sidebar" page_lookup as varname %}
    {% page_placeholder "sidebar" page_lookup or %}
        <div>No content</div>
    {% endpage_placeholder %}
    Keyword arguments:
        name: the name of the placeholder
        page_lookup: lookup argument for Page. See _get_page_by_untyped_arg() for detailed
            information on the allowed types and their interpretation for the page_lookup argument.
        inherit : optional argument which if given will result in inheriting
            the content of the placeholder with the same name on parent pages
        varname: context variable name. Output will be added to template context as this variable
            instead of being returned.
        or: optional argument which if given will make the template tag a block
            tag whose content is shown if the placeholder is empty
    """

    name = "page_placeholder"
    options = PlaceholderOptions(
        Argument("name", resolve=False),
        Argument("page_lookup"),
        MultiValueArgument("extra_bits", required=False, resolve=False),
        blocks=[("endpage_placeholder", "nodelist")],
    )

    # pylint: disable=arguments-differ,too-many-arguments
    def render_tag(self,
                   context,
                   name,
                   page_lookup,
                   extra_bits,
                   nodelist=None):
        validate_placeholder_name(name)

        request = context.get("request")

        if request:
            page = _get_page_by_untyped_arg(page_lookup, request,
                                            get_site_id(None))

            toolbar = get_toolbar_from_request(request)
            renderer = toolbar.get_content_renderer()

            inherit = "inherit" in extra_bits

            # A placeholder is only editable on its own page
            editable = page == request.current_page

            try:
                content = renderer.render_page_placeholder(
                    slot=name,
                    context=context,
                    inherit=inherit,
                    page=page,
                    nodelist=nodelist,
                    editable=editable,
                )
            except PlaceholderNotFound:
                content = ""
        else:
            content = ""

        if not content and nodelist:
            content = nodelist.render(context)

        if "as" in extra_bits:
            try:
                varname = extra_bits[extra_bits.index("as") + 1]
            except IndexError:
                raise template.TemplateSyntaxError(
                    'the "as" word should be followed by the variable name')
            context[varname] = content
            return ""

        return content
class StaticAlias(Tag):
    """
    This template node is used to render Alias contents and is designed to be a
    replacement for the CMS Static Placeholder.

    eg: {% static_alias "identifier_text" %}
    eg: {% static_alias "identifier_text" site %}

    Keyword arguments:
    static_code -- the unique identifier of the Alias
    site -- If site is supplied an Alias instance will be created per site.
    """
    name = 'static_alias'
    options = PlaceholderOptions(
        Argument('static_code', resolve=False),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        blocks=[
            ('endstatic_alias', 'nodelist'),
        ],
    )

    def _get_alias(self, request, static_code, extra_bits):
        alias_filter_kwargs = {
            'static_code': static_code,
        }
        # Site
        current_site = get_current_site()
        if 'site' in extra_bits:
            alias_filter_kwargs['site'] = current_site
        else:
            alias_filter_kwargs['site_id__isnull'] = True

        # Try and find an Alias to render
        alias = Alias.objects.filter(**alias_filter_kwargs).first()
        # If there is no alias found we need to create one
        if not alias:

            # If versioning is enabled we can only create the records with a logged in user / staff member
            if is_versioning_enabled() and not request.user.is_authenticated:
                return None

            language = get_default_language_for_site(current_site)
            # Parlers get_or_create doesn't work well with translations, so we must perform our own get or create
            default_category = Category.objects.filter(translations__name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME).first()
            if not default_category:
                default_category = Category.objects.create(name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME)

            alias_creation_kwargs = {
                'static_code': static_code,
                'creation_method': Alias.CREATION_BY_TEMPLATE
            }
            # Site
            if 'site' in extra_bits:
                alias_creation_kwargs['site'] = current_site

            alias = Alias.objects.create(category=default_category, **alias_creation_kwargs)
            alias_content = AliasContent.objects.create(
                alias=alias,
                name=static_code,
                language=language,
            )

            if is_versioning_enabled():
                from djangocms_versioning.models import Version

                Version.objects.create(content=alias_content, created_by=request.user)

        return alias

    def render_tag(self, context, static_code, extra_bits, nodelist=None):
        request = context.get('request')

        if not static_code or not request:
            # an empty string was passed in or the variable is not available in the context
            if nodelist:
                return nodelist.render(context)
            return ''

        validate_placeholder_name(static_code)

        toolbar = get_toolbar_from_request(request)
        renderer = toolbar.get_content_renderer()
        alias = self._get_alias(request, static_code, extra_bits)

        if not alias:
            return ''

        # Get draft contents in edit or preview mode?
        get_draft_content = False
        if toolbar.edit_mode_active or toolbar.preview_mode_active:
            get_draft_content = True

        language = get_language_from_request(request)
        placeholder = alias.get_placeholder(language=language, show_draft_content=get_draft_content)

        if placeholder:
            content = renderer.render_placeholder(
                placeholder=placeholder,
                context=context,
                nodelist=nodelist,
            )
            return content
        return ''
示例#26
0
class Placeholder(Tag):
    """
    This template node is used to output page content and
    is also used in the admin to dynamically generate input fields.

    eg: {% placeholder "placeholder_name" %}

    {% placeholder "sidebar" inherit %}

    {% placeholder "footer" inherit or %}
        <a href="/about/">About us</a>
    {% endplaceholder %}

    Keyword arguments:
    name -- the name of the placeholder
    inherit -- optional argument which if given will result in inheriting
        the content of the placeholder with the same name on parent pages
    or -- optional argument which if given will make the template tag a block
        tag whose content is shown if the placeholder is empty
    """
    name = 'placeholder'
    options = PlaceholderOptions(
        Argument('name', resolve=False),
        MultiValueArgument('extra_bits', required=False, resolve=False),
        blocks=[
            ('endplaceholder', 'nodelist'),
        ],
    )

    def render_tag(self, context, name, extra_bits, nodelist=None):
        request = context.get('request')

        if not request:
            return ''

        validate_placeholder_name(name)

        toolbar = get_toolbar_from_request(request)
        renderer = toolbar.get_content_renderer()
        inherit = 'inherit' in extra_bits

        try:
            content = renderer.render_page_placeholder(
                slot=name,
                context=context,
                inherit=inherit,
                nodelist=nodelist,
            )
        except PlaceholderNotFound:
            content = ''

        if not content and nodelist:
            return nodelist.render(context)
        return content

    def get_declaration(self):
        flags = self.kwargs['extra_bits']
        slot = self.kwargs['name'].var.value.strip('"').strip("'")

        if isinstance(flags, ListValue):
            inherit = any(extra.var.value.strip() == 'inherit'
                          for extra in flags)
            return DeclaredPlaceholder(slot=slot, inherit=inherit)
        return DeclaredPlaceholder(slot=slot, inherit=False)
示例#27
0
class Placeholder(Tag):
    """
    This template node is used to output page content and
    is also used in the admin to dynamically generate input fields.

    eg: {% placeholder "placeholder_name" %}

    {% placeholder "sidebar" inherit %}

    {% placeholder "footer" inherit or %}
        <a href="/about/">About us</a>
    {% endplaceholder %}

    Keyword arguments:
    name -- the name of the placeholder
    width -- additional width attribute (integer) which gets added to the plugin context
    (deprecated, use `{% with 320 as width %}{% placeholder "foo"}{% endwith %}`)
    inherit -- optional argument which if given will result in inheriting
        the content of the placeholder with the same name on parent pages
    or -- optional argument which if given will make the template tag a block
        tag whose content is shown if the placeholder is empty
    """
    name = 'placeholder'
    options = PlaceholderOptions(Argument('name', resolve=False),
                                 MultiValueArgument('extra_bits',
                                                    required=False,
                                                    resolve=False),
                                 blocks=[
                                     ('endplaceholder', 'nodelist'),
                                 ])

    def render_tag(self, context, name, extra_bits, nodelist=None):
        validate_placeholder_name(name)
        width = None
        inherit = False
        for bit in extra_bits:
            if bit == 'inherit':
                inherit = True
            elif bit.isdigit():
                width = int(bit)
                import warnings

                warnings.warn(
                    "The width parameter for the placeholder tag is deprecated.",
                    DeprecationWarning)
        if not 'request' in context:
            return ''
        request = context['request']
        if width:
            context.update({'width': width})

        page = request.current_page
        if not page or page == 'dummy':
            if nodelist:
                return nodelist.render(context)

            return ''

        content = get_placeholder_content(context, request, page, name,
                                          inherit)
        if not content and nodelist:
            return nodelist.render(context)
        return content

    def get_name(self):
        return self.kwargs['name'].var.value.strip('"').strip("'")
示例#28
0
class GetPlaceholderPlugins(Placeholder):
    """
    A template tag that declares a placeholder and sets its plugins as a context variable
    instead of rendering them eg:

        {% get_placeholder_plugins "logo" as varname %}
        {% get_placeholder_plugins "logo" page_lookup as varname %}
        {% get_placeholder_plugins "logo" page_lookup as varname or %}
            <div>No content</div>
        {% endget_placeholder_plugins %}

    This tag can typically be used in association with the block_plugin tag, in a placeholder
    limited to one plugin, to customize the way it is rendered eg:

        {% get_placeholder_plugins "logo" page_lookup as plugins %}
        {% blockplugin plugins.0 %}
            <img src="{% thumbnail instance.picture 300x150 %}"/>
        {% endblockplugin %}

    Keyword arguments:
        name: the name of the placeholder
        page_lookup[optional]: lookup argument for Page. See `_get_page_by_untyped_arg()`
            for detailed information on the allowed types and their interpretation for the
            `page_lookup` argument.
        varname: context variable name. Output will be added to template context as this variable
            instead of being returned.
        or: optional argument which if given will make the template tag a block
            tag whose content is shown if the placeholder is empty

    Note: We must derive from the Placeholder class so that the tag is recognized as a
          placeholder and shown in the structure toolbar.
    """

    name = "get_placeholder_plugins"
    options = PlaceholderOptions(
        Argument("name", resolve=False),
        Argument("page_lookup", required=False),
        "as",
        Argument("varname", resolve=False),
        MultiValueArgument("extra_bits", required=False, resolve=False),
        blocks=[("endget_placeholder_plugins", "nodelist")],
    )

    # pylint: disable=arguments-differ,too-many-arguments
    def render_tag(self,
                   context,
                   name,
                   page_lookup,
                   varname,
                   extra_bits,
                   nodelist=None):
        """
        Retrieves the placeholder's plugins and set them as a variable in the template context.
        If the placeholder is empty, render the block as fallback content and return the
        resulting HTML.
        If the placholder is editable, the edit script and markup are added to the HTML content.
        """
        content = ""
        request = context.get("request")

        if request:

            page = _get_page_by_untyped_arg(page_lookup, request,
                                            get_site_id(None))

            try:
                placeholder = page.placeholders.get(slot=name)
            except ObjectDoesNotExist:
                context[varname] = []
                return ""
            else:
                context[varname] = [
                    cms_plugin.get_plugin_instance()[0]
                    for cms_plugin in get_plugins(
                        request, placeholder, template=page.get_template())
                ]

            # Default content if there is no plugins in the placeholder
            if not context[varname] and nodelist:
                content = nodelist.render(context)

            # Add the edit script and markup to the content, only if the placeholder is editable
            # and the visited page is the one on which the placeholder is declared.
            toolbar = get_toolbar_from_request(request)
            if placeholder.page == request.current_page and toolbar.edit_mode_active:
                renderer = toolbar.get_content_renderer()
                data = renderer.get_editable_placeholder_context(placeholder,
                                                                 page=page)
                data["content"] = content
                content = renderer.placeholder_edit_template.format(**data)

        return content