Example #1
0
    def render(self, context):
        request = self.get_request(context)

        # Get the placeholder
        parent = self.parent_expr.resolve(context)
        slot = self.slot_expr.resolve(context)
        fallback_language = self._is_true(self.fallback_expr.resolve(
            context)) if self.fallback_expr else False
        try:
            placeholder = Placeholder.objects.get_by_slot(parent, slot)
        except Placeholder.DoesNotExist:
            return "<!-- placeholder '{0}' does not yet exist -->".format(slot)

        template_name = self.template_expr.resolve(
            context) if self.template_expr else None

        output = rendering.render_placeholder(
            request,
            placeholder,
            parent,
            template_name=template_name,
            fallback_language=fallback_language)
        rendering.register_frontend_media(
            request, output.media
        )  # Assume it doesn't hurt. TODO: should this be optional?
        return output.html
Example #2
0
    def get_value(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)

        # Parse arguments
        try:
            placeholder = _get_placeholder_arg(self.args[0], tag_args[0])
        except RuntimeWarning as e:
            return u"<!-- {0} -->".format(e)

        template_name = tag_kwargs.get('template', None)
        cachable = is_true(tag_kwargs.get('cachable', not bool(template_name)))  # default: True unless there is a template.
        fallback_language = is_true(tag_kwargs.get('fallback', False))

        if template_name and cachable and not extract_literal(self.kwargs['template']):
            # If the template name originates from a variable, it can change any time.
            # See PagePlaceholderNode.render_tag() why this is not allowed.
            raise TemplateSyntaxError("{0} tag does not allow 'cachable' for variable template names!".format(self.tag_name))

        # Fetching placeholder.parent should not cause queries if fetched via PlaceholderFieldDescriptor.
        # See render_placeholder() for more details
        output = rendering.render_placeholder(request, placeholder, placeholder.parent,
            template_name=template_name,
            cachable=cachable,
            limit_parent_language=True,
            fallback_language=fallback_language
        )
        rendering.register_frontend_media(request, output.media)   # Need to track frontend media here, as the template tag can't return it.
        return output.html
    def get_value(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)
        output = None

        # Process arguments
        (slot,) = tag_args
        template_name = tag_kwargs.get('template') or None
        cachable = is_true(tag_kwargs.get('cachable', not bool(template_name)))  # default: True unless there is a template.

        if template_name and cachable and not extract_literal(self.kwargs['template']):
            # If the template name originates from a variable, it can change any time.
            # See PagePlaceholderNode.render_tag() why this is not allowed.
            raise TemplateSyntaxError("{0} tag does not allow 'cachable' for variable template names!".format(self.tag_name))

        # Caching will not happen when rendering via a template,
        # because there is no way to tell whether that can be expired/invalidated.
        try_cache = appsettings.FLUENT_CONTENTS_CACHE_OUTPUT \
                and appsettings.FLUENT_CONTENTS_CACHE_PLACEHOLDER_OUTPUT \
                and cachable

        if isinstance(slot, SharedContent):
            # Allow passing a sharedcontent, just like 'render_placeholder' does.
            sharedcontent = slot

            # See if there is cached output, avoid fetching the Placeholder via sharedcontents.contents.
            if try_cache:
                cache_key = get_shared_content_cache_key(sharedcontent)
                output = cache.get(cache_key)
        else:
            site = Site.objects.get_current()
            if try_cache:
                # See if there is output cached, try to avoid fetching the SharedContent + Placeholder model.
                # Have to perform 2 cache calls for this, because the placeholder output key is based on object IDs
                cache_key_ptr = get_shared_content_cache_key_ptr(int(site.pk), slot, language_code=get_language())
                cache_key = cache.get(cache_key_ptr)
                if cache_key is not None:
                    output = cache.get(cache_key)

            if output is None:
                # Get the placeholder
                try:
                    sharedcontent = SharedContent.objects.parent_site(site).get(slug=slot)
                except SharedContent.DoesNotExist:
                    return "<!-- shared content '{0}' does not yet exist -->".format(slot)

                # Now that we've fetched the object, the object key be generated.
                # No real need to check for output again, render_placeholder() does that already.
                if try_cache and not cache_key:
                    cache.set(cache_key_ptr, get_shared_content_cache_key(sharedcontent))

        if output is None:
            # Have to fetch + render it.
            output = self.render_shared_content(request, sharedcontent, template_name, cachable=cachable)

        rendering.register_frontend_media(request, output.media)  # Need to track frontend media here, as the template tag can't return it.
        return output.html
Example #4
0
    def get_value(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)
        output = None

        # Process arguments
        parent, slot = tag_args
        template_name = tag_kwargs.get("template", None)
        # cachable default is True unless there is a template.
        cachable = is_true(tag_kwargs.get("cachable", not bool(template_name)))
        fallback_language = is_true(tag_kwargs.get("fallback", False))

        if template_name and cachable and not extract_literal(self.kwargs["template"]):
            # If the template name originates from a variable, it can change any time.
            # It's not possible to create a reliable output cache for for that,
            # as it would have to include any possible template name in the key.
            raise TemplateSyntaxError(
                "{} tag does not allow 'cachable' for variable template names!".format(
                    self.tag_name
                )
            )

        if (
            appsettings.FLUENT_CONTENTS_CACHE_OUTPUT
            and appsettings.FLUENT_CONTENTS_CACHE_PLACEHOLDER_OUTPUT
            and cachable
        ):
            # See if the entire placeholder output is cached,
            # if so, no database queries have to be performed.
            # This will be omitted when an template is used,
            # because there is no way to expire that or tell whether that template is cacheable.
            output = get_cached_placeholder_output(parent, slot)

        if output is None:
            # Get the placeholder
            try:
                placeholder = Placeholder.objects.get_by_slot(parent, slot)
            except Placeholder.DoesNotExist:
                return f"<!-- placeholder '{slot}' does not yet exist -->"

            output = rendering.render_placeholder(
                request,
                placeholder,
                parent,
                template_name=template_name,
                cachable=cachable,
                limit_parent_language=True,
                fallback_language=fallback_language,
            )

        # Assume it doesn't hurt to register media. TODO: should this be optional?
        rendering.register_frontend_media(request, output.media)
        return output.html
    def render_tag(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)

        try:
            placeholder = _get_placeholder_arg(self.args[0], tag_args[0])
        except RuntimeWarning as e:
            return u"<!-- {0} -->".format(e)

        # To support filtering the placeholders by parent language, the parent object needs to be known.
        # Fortunately, the PlaceholderFieldDescriptor makes sure this doesn't require an additional query.
        parent_object = placeholder.parent

        output = rendering.render_placeholder(request, placeholder, parent_object)
        rendering.register_frontend_media(request, output.media)   # Assume it doesn't hurt. TODO: should this be optional?
        return output.html
    def render(self, context):
        request = self.get_request(context)

        # Get the placeholder
        parent = self.parent_expr.resolve(context)
        slot = self.slot_expr.resolve(context)
        try:
            placeholder = Placeholder.objects.get_by_slot(parent, slot)
        except Placeholder.DoesNotExist:
            return "<!-- placeholder '{0}' does not yet exist -->".format(slot)

        template_name = self.template_expr.resolve(context) if self.template_expr else None

        output = rendering.render_placeholder(request, placeholder, parent, template_name=template_name)
        rendering.register_frontend_media(request, output.media)   # Assume it doesn't hurt. TODO: should this be optional?
        return output.html
Example #7
0
    def render_tag(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)

        try:
            placeholder = _get_placeholder_arg(self.args[0], tag_args[0])
        except RuntimeWarning as e:
            return u"<!-- {0} -->".format(e)

        # To support filtering the placeholders by parent language, the parent object needs to be known.
        # Fortunately, the PlaceholderFieldDescriptor makes sure this doesn't require an additional query.
        parent_object = placeholder.parent

        output = rendering.render_placeholder(request, placeholder,
                                              parent_object)
        rendering.register_frontend_media(
            request, output.media
        )  # Assume it doesn't hurt. TODO: should this be optional?
        return output.html
    def get_value(self, context, *tag_args, **tag_kwargs):
        request = self.get_request(context)
        output = None

        # Process arguments
        parent, slot = tag_args
        template_name = tag_kwargs.get('template', None)
        cachable = is_true(tag_kwargs.get('cachable', not bool(template_name)))  # default: True unless there is a template.
        fallback_language = is_true(tag_kwargs.get('fallback', False))

        if template_name and cachable and not extract_literal(self.kwargs['template']):
            # If the template name originates from a variable, it can change any time.
            # It's not possible to create a reliable output cache for for that,
            # as it would have to include any possible template name in the key.
            raise TemplateSyntaxError("{0} tag does not allow 'cachable' for variable template names!".format(self.tag_name))

        if appsettings.FLUENT_CONTENTS_CACHE_OUTPUT \
        and appsettings.FLUENT_CONTENTS_CACHE_PLACEHOLDER_OUTPUT \
        and cachable:
            # See if the entire placeholder output is cached,
            # if so, no database queries have to be performed.
            # This will be omitted when an template is used,
            # because there is no way to expire that or tell whether that template is cacheable.
            output = get_cached_placeholder_output(parent, slot)

        if output is None:
            # Get the placeholder
            try:
                placeholder = Placeholder.objects.get_by_slot(parent, slot)
            except Placeholder.DoesNotExist:
                return "<!-- placeholder '{0}' does not yet exist -->".format(slot)

            output = rendering.render_placeholder(request, placeholder, parent,
                template_name=template_name,
                cachable=cachable,
                limit_parent_language=True,
                fallback_language=fallback_language
            )

        rendering.register_frontend_media(request, output.media)   # Assume it doesn't hurt. TODO: should this be optional?
        return output.html
 def render_shared_content(self, request, sharedcontent, template_name):
     # All parsing done, perform the actual rendering
     output = rendering.render_placeholder(request, sharedcontent.contents, sharedcontent, template_name=template_name, fallback_language=True)
     rendering.register_frontend_media(request, output.media)  # Need to track frontend media here, as the template tag can't return it.
     return output.html