예제 #1
0
    def _get_placeholder_items(self, placeholder, parent_object, limit_parent_language, fallback_language, try_cache):
        # No full-placeholder cache. Get the items
        items = placeholder.get_content_items(parent_object, limit_parent_language=limit_parent_language).non_polymorphic()
        if 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. Try it.
            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()
            return items, True
        else:
            return items, False
예제 #2
0
    def _get_placeholder_items(self, placeholder, parent_object,
                               limit_parent_language, fallback_language,
                               try_cache):
        # No full-placeholder cache. Get the items
        items = placeholder.get_content_items(
            parent_object,
            limit_parent_language=limit_parent_language).non_polymorphic()
        if 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. Try it.
            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()
            return items, True
        else:
            return items, False
예제 #3
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
예제 #4
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