Пример #1
0
    def render_placeholder(self,
                           placeholder,
                           parent_object=None,
                           template_name=None,
                           cachable=None,
                           limit_parent_language=True,
                           fallback_language=None):
        """
        The main rendering sequence for placeholders.
        This will do all the magic for caching, and call :func:`render_items` in the end.
        """
        placeholder_name = get_placeholder_debug_name(placeholder)
        logger.debug("Rendering placeholder '%s'", placeholder_name)

        # Determine whether the placeholder can be cached.
        cachable = self._can_cache_merged_output(template_name, cachable)
        try_cache = cachable and self.may_cache_placeholders()
        logger.debug("- try_cache=%s cachable=%s template_name=%s", try_cache,
                     cachable, template_name)

        if parent_object is None:
            # 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

        # Fetch the placeholder output from cache.
        language_code = get_parent_language_code(parent_object)
        cache_key = None
        output = None
        if try_cache:
            cache_key = get_placeholder_cache_key_for_parent(
                parent_object, placeholder.slot, language_code)
            output = cache.get(cache_key)
            if output:
                logger.debug("- fetched cached output")

        if output is None:
            # Get the items, and render them
            items, is_fallback = self._get_placeholder_items(
                placeholder, parent_object, limit_parent_language,
                fallback_language, try_cache)
            output = self.render_items(placeholder, items, parent_object,
                                       template_name, cachable)

            if is_fallback:
                # Caching fallbacks is not supported yet,
                # content could be rendered in a different gettext language domain.
                output.cacheable = False

            # Store the full-placeholder contents in the cache.
            if try_cache and output.cacheable:
                if output.cache_timeout is not DEFAULT_TIMEOUT:
                    # The timeout is based on the minimal timeout used in plugins.
                    cache.set(cache_key, output, output.cache_timeout)
                else:
                    # Don't want to mix into the default 0/None issue.
                    cache.set(cache_key, output)

        return output
Пример #2
0
def get_cached_placeholder_output(parent_object, placeholder_name):
    """
    Return cached output for a placeholder, if available.
    This avoids fetching the Placeholder object.
    """
    if not appsettings.FLUENT_CONTENTS_CACHE_OUTPUT or not appsettings.FLUENT_CONTENTS_CACHE_PLACEHOLDER_OUTPUT:
        return None

    language_code = get_parent_language_code(parent_object)
    cache_key = get_placeholder_cache_key_for_parent(parent_object, placeholder_name, language_code)
    return cache.get(cache_key)
Пример #3
0
def get_cached_placeholder_output(parent_object, placeholder_name):
    """
    Return cached output for a placeholder, if available.
    This avoids fetching the Placeholder object.
    """
    if not PlaceholderRenderingPipe.may_cache_placeholders():
        return None

    language_code = get_parent_language_code(parent_object)
    cache_key = get_placeholder_cache_key_for_parent(parent_object, placeholder_name, language_code)
    return cache.get(cache_key)
Пример #4
0
def get_cached_placeholder_output(parent_object, placeholder_name):
    """
    Return cached output for a placeholder, if available.
    This avoids fetching the Placeholder object.
    """
    if not PlaceholderRenderingPipe.may_cache_placeholders():
        return None

    language_code = get_parent_language_code(parent_object)
    cache_key = get_placeholder_cache_key_for_parent(parent_object,
                                                     placeholder_name,
                                                     language_code)
    return cache.get(cache_key)
Пример #5
0
def get_cached_placeholder_output(parent_object, placeholder_name):
    """
    Return cached output for a placeholder, if available.
    This avoids fetching the Placeholder object.
    """
    if not appsettings.FLUENT_CONTENTS_CACHE_OUTPUT \
    or not appsettings.FLUENT_CONTENTS_CACHE_PLACEHOLDER_OUTPUT:
        return None

    language_code = get_parent_language_code(parent_object)
    cache_key = get_placeholder_cache_key_for_parent(parent_object,
                                                     placeholder_name,
                                                     language_code)
    return cache.get(cache_key)
Пример #6
0
    def render_placeholder(self, placeholder, parent_object=None, template_name=None, cachable=None, limit_parent_language=True, fallback_language=None):
        """
        The main rendering sequence for placeholders.
        This will do all the magic for caching, and call :func:`render_items` in the end.
        """
        placeholder_name = get_placeholder_debug_name(placeholder)
        logger.debug("Rendering placeholder '%s'", placeholder_name)

        # Determine whether the placeholder can be cached.
        cachable = self._can_cache_merged_output(template_name, cachable)
        try_cache = cachable and self.may_cache_placeholders()
        logger.debug("- try_cache=%s cachable=%s template_name=%s", try_cache, cachable, template_name)

        if parent_object is None:
            # 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

        # Fetch the placeholder output from cache.
        language_code = get_parent_language_code(parent_object)
        cache_key = None
        output = None
        if try_cache:
            cache_key = get_placeholder_cache_key_for_parent(parent_object, placeholder.slot, language_code)
            output = cache.get(cache_key)
            if output:
                logger.debug("- fetched cached output")

        if output is None:
            # Get the items, and render them
            items, is_fallback = self._get_placeholder_items(placeholder, parent_object, limit_parent_language, fallback_language, try_cache)
            output = self.render_items(placeholder, items, parent_object, template_name, cachable)

            if is_fallback:
                # Caching fallbacks is not supported yet,
                # content could be rendered in a different gettext language domain.
                output.cacheable = False

            # Store the full-placeholder contents in the cache.
            if try_cache and output.cacheable:
                if output.cache_timeout is not DEFAULT_TIMEOUT:
                    # The timeout is based on the minimal timeout used in plugins.
                    cache.set(cache_key, output, output.cache_timeout)
                else:
                    # Don't want to mix into the default 0/None issue.
                    cache.set(cache_key, output)

        return output
Пример #7
0
def get_shared_content_cache_key(sharedcontent):
    # Generate the key that render_placeholder() would use to store all output in.
    return get_placeholder_cache_key_for_parent(
        sharedcontent, "shared_content", sharedcontent.get_current_language())
Пример #8
0
def render_placeholder(
    request,
    placeholder,
    parent_object=None,
    template_name=None,
    cachable=None,
    limit_parent_language=True,
    fallback_language=None,
):
    """
    Render a :class:`~fluent_contents.models.Placeholder` object.
    Returns a :class:`~fluent_contents.models.ContentItemOutput` object
    which contains the HTML output and :class:`~django.forms.Media` object.

    This function also caches the complete output of the placeholder
    when all individual items are cacheable.

    :param request: The current request object.
    :type request: :class:`~django.http.HttpRequest`
    :param placeholder: The placeholder object.
    :type placeholder: :class:`~fluent_contents.models.Placeholder`
    :param parent_object: Optional, the parent object of the placeholder (already implied by the placeholder)
    :param template_name: Optional template name used to concatenate the placeholder output.
    :type template_name: str | None
    :param cachable: Whether the output is cachable, otherwise the full output will not be cached.
                     Default: False when using a template, True otherwise.
    :type cachable: bool | None
    :param limit_parent_language: Whether the items should be limited to the parent language.
    :type limit_parent_language: bool
    :param fallback_language: The fallback language to use if there are no items in the current language. Passing ``True`` uses the default :ref:`FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE`.
    :type fallback_language: bool/str
    :rtype: :class:`~fluent_contents.models.ContentItemOutput`
    """
    _optimize_logger()
    placeholder_name = _get_placeholder_name(placeholder)
    logger.debug("Rendering placeholder '%s'", placeholder_name)

    if cachable is None:
        # default: True unless there is a template.
        cachable = not bool(template_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
    )
    cache_key = None
    output = None

    logger.debug("- try_cache=%s cachable=%s template_name=%s", try_cache, cachable, template_name)

    if parent_object is None:
        # 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

    language_code = get_parent_language_code(parent_object)
    if try_cache:
        cache_key = get_placeholder_cache_key_for_parent(parent_object, placeholder.slot, language_code)
        output = cache.get(cache_key)

    if output is None:
        # No full-placeholder cache. Get the items
        items = placeholder.get_content_items(
            parent_object, limit_parent_language=limit_parent_language
        ).non_polymorphic()
        if _LOG_DEBUG and is_queryset_empty(items):  # Detect qs.none() was applied
            logging.debug("- skipping regular language, parent object has no translation for it.")

        if fallback_language and not items:  # NOTES: performs query, so hence the .non_polymorphic() above
            # There are no items, but there is a fallback option.
            # This is not supported yet, content can be rendered in a different gettext language domain.
            try_cache = False

            language_code = (
                appsettings.FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE if fallback_language is True else fallback_language
            )
            logger.debug("- reading fallback language %s, try_cache=%s", language_code, try_cache)
            items = (
                placeholder.get_content_items(parent_object, limit_parent_language=False)
                .translated(language_code)
                .non_polymorphic()
            )

        output = _render_items(
            request, placeholder, items, parent_object=parent_object, template_name=template_name, cachable=cachable
        )

        # Store the full-placeholder contents in the cache.
        if try_cache and output.cacheable and cache_key is not None:
            # The timeout takes notice of the minimal timeout used in plugins.
            if output.cache_timeout is not DEFAULT_TIMEOUT:
                cache.set(cache_key, output, output.cache_timeout)
            else:
                # Don't want to mix into the default 0/None issue.
                cache.set(cache_key, output)
    else:
        logger.debug("- fetched cached output")

    if is_edit_mode(request):
        output.html = _wrap_placeholder_output(output.html, placeholder)

    return output
Пример #9
0
def render_placeholder(request, placeholder, parent_object=None, template_name=None, template_cachable=False, limit_parent_language=True, fallback_language=None):
    """
    Render a :class:`~fluent_contents.models.Placeholder` object.
    Returns a :class:`~fluent_contents.models.ContentItemOutput` object
    which contains the HTML output and :class:`~django.forms.Media` object.

    This function also caches the complete output of the placeholder
    when all individual items are cacheable.

    :param request: The current request object.
    :type request: :class:`~django.http.HttpRequest`
    :param placeholder: The placeholder object.
    :type placeholder: :class:`~fluent_contents.models.Placeholder`
    :param parent_object: Optional, the parent object of the placeholder (already implied by the placeholder)
    :param template_name: Optional template name used to concatenate the placeholder output.
    :type template_name: str | None
    :param template_cachable: Whether the provided template is cachable, otherwise the full output will not be cached.
    :type template_cachable: bool
    :param limit_parent_language: Whether the items should be limited to the parent language.
    :type limit_parent_language: bool
    :param fallback_language: The fallback language to use if there are no items in the current language. Passing ``True`` uses the default :ref:`FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE`.
    :type fallback_language: bool/str
    :rtype: :class:`~fluent_contents.models.ContentItemOutput`
    """
    # 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 (not template_name or template_cachable)
    cache_key = None
    output = None

    if parent_object is None:
        # 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

    language_code = get_parent_language_code(parent_object)
    if try_cache:
        cache_key = get_placeholder_cache_key_for_parent(parent_object, placeholder.slot, language_code)
        output = cache.get(cache_key)

    if output is None:
        # No full-placeholder cache. Get the items
        items = placeholder.get_content_items(parent_object, limit_parent_language=limit_parent_language).non_polymorphic()
        if fallback_language \
        and not items:  # NOTES: performs query, so hence the .non_polymorphic() above
            # There are no items, but there is a fallback option.
            try_cache = False  # This is not supported yet, content can be rendered in a different gettext language domain.
            language_code = appsettings.FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE if fallback_language is True else fallback_language
            items = placeholder.get_content_items(parent_object, limit_parent_language=False).translated(language_code).non_polymorphic()

        output = _render_items(request, placeholder, items, parent_object=parent_object, template_name=template_name, template_cachable=template_cachable)

        # Store the full-placeholder contents in the cache.
        if try_cache and output.cacheable and cache_key is not None:
            cache.set(cache_key, output)

    if is_edit_mode(request):
        output.html = _wrap_placeholder_output(output.html, placeholder)

    return output
Пример #10
0
def render_placeholder(request,
                       placeholder,
                       parent_object=None,
                       template_name=None,
                       cachable=None,
                       limit_parent_language=True,
                       fallback_language=None):
    """
    Render a :class:`~fluent_contents.models.Placeholder` object.
    Returns a :class:`~fluent_contents.models.ContentItemOutput` object
    which contains the HTML output and :class:`~django.forms.Media` object.

    This function also caches the complete output of the placeholder
    when all individual items are cacheable.

    :param request: The current request object.
    :type request: :class:`~django.http.HttpRequest`
    :param placeholder: The placeholder object.
    :type placeholder: :class:`~fluent_contents.models.Placeholder`
    :param parent_object: Optional, the parent object of the placeholder (already implied by the placeholder)
    :param template_name: Optional template name used to concatenate the placeholder output.
    :type template_name: str | None
    :param cachable: Whether the output is cachable, otherwise the full output will not be cached.
                     Default: False when using a template, True otherwise.
    :type cachable: bool | None
    :param limit_parent_language: Whether the items should be limited to the parent language.
    :type limit_parent_language: bool
    :param fallback_language: The fallback language to use if there are no items in the current language. Passing ``True`` uses the default :ref:`FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE`.
    :type fallback_language: bool/str
    :rtype: :class:`~fluent_contents.models.ContentItemOutput`
    """
    _optimize_logger()
    placeholder_name = _get_placeholder_name(placeholder)
    logger.debug("Rendering placeholder '%s'", placeholder_name)

    if cachable is None:
        # default: True unless there is a template.
        cachable = not bool(template_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
    cache_key = None
    output = None

    logger.debug("- try_cache=%s cachable=%s template_name=%s", try_cache,
                 cachable, template_name)

    if parent_object is None:
        # 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

    language_code = get_parent_language_code(parent_object)
    if try_cache:
        cache_key = get_placeholder_cache_key_for_parent(
            parent_object, placeholder.slot, language_code)
        output = cache.get(cache_key)

    if output is None:
        # No full-placeholder cache. Get the items
        items = placeholder.get_content_items(
            parent_object,
            limit_parent_language=limit_parent_language).non_polymorphic()
        if _LOG_DEBUG and is_queryset_empty(
                items):  # Detect qs.none() was applied
            logging.debug(
                "- skipping regular language, parent object has no translation for it."
            )

        if fallback_language \
        and not items:  # NOTES: performs query, so hence the .non_polymorphic() above
            # There are no items, but there is a fallback option.
            # This is not supported yet, content can be rendered in a different gettext language domain.
            try_cache = False

            language_code = appsettings.FLUENT_CONTENTS_DEFAULT_LANGUAGE_CODE if fallback_language is True else fallback_language
            logger.debug("- reading fallback language %s, try_cache=%s",
                         language_code, try_cache)
            items = placeholder.get_content_items(
                parent_object, limit_parent_language=False).translated(
                    language_code).non_polymorphic()

        output = _render_items(request,
                               placeholder,
                               items,
                               parent_object=parent_object,
                               template_name=template_name,
                               cachable=cachable)

        # Store the full-placeholder contents in the cache.
        if try_cache and output.cacheable and cache_key is not None:
            # The timeout takes notice of the minimal timeout used in plugins.
            if output.cache_timeout is not DEFAULT_TIMEOUT:
                cache.set(cache_key, output, output.cache_timeout)
            else:
                # Don't want to mix into the default 0/None issue.
                cache.set(cache_key, output)
    else:
        logger.debug("- fetched cached output")

    if is_edit_mode(request):
        output.html = _wrap_placeholder_output(output.html, placeholder)

    return output
Пример #11
0
def get_shared_content_cache_key(sharedcontent):
    # Generate the key that render_placeholder() would use to store all output in.
    return get_placeholder_cache_key_for_parent(sharedcontent, 'shared_content', sharedcontent.get_current_language())