Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions integreat_cms/api/v3/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def transform_event_translation(
else f"{event_translation.slug}${recurrence_date}"
)
absolute_url = event_translation.url_prefix + slug + "/"
content = event_translation.content_for_delivery()
return {
"id": event_translation.id,
"url": settings.BASE_URL + absolute_url,
Expand All @@ -92,8 +93,8 @@ def transform_event_translation(
"published_at": timezone.localtime(
event_translation.published_at or event_translation.last_updated,
),
"excerpt": strip_tags(event_translation.content),
"content": event_translation.content,
"excerpt": strip_tags(content),
"content": content,
"available_languages": (
transform_available_languages(event_translation, recurrence_date)
if recurrence_date
Expand Down
5 changes: 3 additions & 2 deletions integreat_cms/api/v3/imprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ def transform_imprint(imprint_translation: ImprintPageTranslation) -> dict[str,
:return: data necessary for API
"""
absolute_url = imprint_translation.get_absolute_url()
content = imprint_translation.content_for_delivery()
return {
"id": imprint_translation.id,
"url": settings.BASE_URL + absolute_url,
"path": absolute_url,
"title": imprint_translation.title,
"modified_gmt": imprint_translation.last_updated, # deprecated field in the future
"last_updated": timezone.localtime(imprint_translation.last_updated),
"excerpt": strip_tags(imprint_translation.content),
"content": imprint_translation.content,
"excerpt": strip_tags(content),
"content": content,
"parent": None,
"available_languages": imprint_translation.available_languages_dict,
"thumbnail": None,
Expand Down
5 changes: 3 additions & 2 deletions integreat_cms/api/v3/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def transform_poi_translation(
:return: Data for the APIv3 locations endpoint.
"""
poi = poi_translation.poi
content = poi_translation.content_for_delivery()

contacts = Contact.objects.filter(location=poi).all()

Expand Down Expand Up @@ -164,8 +165,8 @@ def transform_poi_translation(
poi_translation.published_at or poi_translation.last_updated,
),
"meta_description": poi_translation.meta_description,
"excerpt": strip_tags(poi_translation.content),
"content": poi_translation.content,
"excerpt": strip_tags(content),
"content": content,
"available_languages": poi_translation.available_languages_dict,
"icon": poi.icon.url if poi.icon else None,
"thumbnail": poi.icon.thumbnail_url if poi.icon else None,
Expand Down
38 changes: 10 additions & 28 deletions integreat_cms/api/v3/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

from ...cms.forms import PageTranslationForm
from ...cms.models import Page, PageTranslation
from ...cms.utils.shortcodes import expand_shortcodes
from ..decorators import json_response, matomo_tracking
from .offers import transform_offer

Expand All @@ -38,13 +37,16 @@
def transform_page(
page_translation: PageTranslation,
page: Page | None = None,
context: dict[str, Any] | None = None,
request: HttpRequest | None = None,
slug_history: list[str] | None = None,
) -> dict[str, Any]:
"""
Function to create a dict from a single page_translation Object.

:param page_translation: single page translation object
:param page: the page the translation belongs to
:param request: the current request, passed to the shortcodes as context
:param slug_history: all slugs this translation has used
:raises ~django.http.Http404: HTTP status 404 if a parent is archived

:return: data necessary for API
Expand Down Expand Up @@ -86,6 +88,7 @@ def transform_page(

organization = page.organization
absolute_url = page_translation.get_absolute_url()
content = page_translation.content_for_delivery(request=request)
return {
"id": page_translation.id,
"url": settings.BASE_URL + absolute_url,
Expand All @@ -96,10 +99,8 @@ def transform_page(
"published_at": timezone.localtime(
page_translation.published_at or page_translation.last_updated,
),
"excerpt": strip_tags(
expand_shortcodes(page_translation.combined_text, context=context)
),
"content": expand_shortcodes(page_translation.combined_text, context=context),
"excerpt": strip_tags(content),
"content": content,
"parent": parent,
"order": order,
"available_languages": page_translation.available_languages_dict,
Expand Down Expand Up @@ -168,12 +169,7 @@ def pages(
transform_page(
page_translation,
page,
context={
"region_slug": region_slug,
"language_slug": language_slug,
"content_object": page_translation,
"request": request,
},
request=request,
slug_history=slug_history.get(page.id, []),
)
)
Expand Down Expand Up @@ -269,12 +265,7 @@ def single_page(
transform_page(
page_translation,
page,
context={
"region_slug": region_slug,
"language_slug": language_slug,
"content_object": page_translation,
"request": request,
},
request=request,
slug_history=list(
dict.fromkeys(
page_translation.all_versions.order_by("version").values_list(
Expand Down Expand Up @@ -355,12 +346,7 @@ def children(
transform_page(
page_translation,
page,
context={
"region_slug": region_slug,
"language_slug": language_slug,
"content_object": page_translation,
"request": request,
},
request=request,
slug_history=slug_history.get(page.id, []),
)
for page in pages.values()
Expand Down Expand Up @@ -428,10 +414,6 @@ def get_public_ancestor_translations(
transform_page(
public_translation,
ancestor,
context={
"language_slug": language_slug,
"content_object": public_translation,
},
slug_history=slug_history.get(ancestor.id, []),
)
)
Expand Down
23 changes: 4 additions & 19 deletions integreat_cms/api/v3/raw_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from ...cms.utils.internal_link_utils import (
get_public_translation_for_webapp_link_parts,
)
from ...cms.utils.shortcodes import expand_shortcodes
from ...cms.utils.social_media_utils import (
get_region_title,
)
Expand All @@ -28,15 +27,12 @@
)

if TYPE_CHECKING:
from typing import Any

from django.http import (
HttpRequest,
HttpResponse,
)

from ...cms.models.abstract_content_translation import AbstractContentTranslation
from ...cms.models.regions.region import Region

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -73,28 +69,17 @@ def render_error_content(request: HttpRequest, error: str) -> HttpResponse:

def get_content(
request: HttpRequest,
region: Region,
language: Language,
translation: AbstractContentTranslation,
) -> str:
"""
Returns the content of a translation with all shortcodes expanded

:param request: The current request
:param region: The region the translation belongs to
:param language: The language of the translation
:param translation: The translation whose content should be rendered

:return: The content of the translation
"""
content = getattr(translation, "combined_text", translation.content)
context: dict[str, Any] = {
"region_slug": region.slug,
"language_slug": language.slug,
"content_object": translation,
"request": request,
}
return expand_shortcodes(content, context=context)
return translation.content_for_delivery(request=request)


@partial_content_response
Expand Down Expand Up @@ -198,7 +183,7 @@ def page_content(
"raw_content.html",
{
"title": get_region_title(region, page_translation.title),
"content": get_content(request, region, language, page_translation),
"content": get_content(request, page_translation),
"language_code": language.bcp47_tag,
},
)
Expand Down Expand Up @@ -240,7 +225,7 @@ def event_content(
"raw_content.html",
{
"title": get_region_title(region, event_translation.title),
"content": get_content(request, region, language, event_translation),
"content": get_content(request, event_translation),
"language_code": language.bcp47_tag,
},
)
Expand Down Expand Up @@ -314,7 +299,7 @@ def location_content(
"raw_content.html",
{
"title": get_region_title(region, location_translation.title),
"content": get_content(request, region, language, location_translation),
"content": get_content(request, location_translation),
"language_code": language.bcp47_tag,
},
)
6 changes: 3 additions & 3 deletions integreat_cms/api/v3/social_media_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def page_social_media_headers(
request=request,
title=get_region_title(region, page_translation.title),
language_code=language.bcp47_tag,
excerpt=get_excerpt(page_translation.content),
excerpt=get_excerpt(page_translation.content_for_delivery()),
url=page_translation.full_url,
)

Expand Down Expand Up @@ -270,7 +270,7 @@ def event_social_media_headers(
request=request,
title=get_region_title(region, event_translation.title),
language_code=language.bcp47_tag,
excerpt=get_excerpt(event_translation.content),
excerpt=get_excerpt(event_translation.content_for_delivery()),
url=event_translation.full_url,
)

Expand Down Expand Up @@ -342,6 +342,6 @@ def location_social_media_headers(
request=request,
title=get_region_title(region, location_translation.title),
language_code=language.bcp47_tag,
excerpt=get_excerpt(location_translation.content),
excerpt=get_excerpt(location_translation.content_for_delivery()),
url=location_translation.full_url,
)
6 changes: 6 additions & 0 deletions integreat_cms/cms/forms/custom_content_model_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ def __init__(self, **kwargs: Any) -> None:
with suppress(ObjectDoesNotExist):
self.locked_by_user = self.instance.foreign_object.get_locking_user()

# References to internal content are stored as shortcodes, but editors should keep
# working with ordinary links, so expand them before they are put into the editor
if "content" in self.fields and self.instance.content:
with suppress(ObjectDoesNotExist):
self.initial["content"] = self.instance.content_for_cms

def clean(self) -> dict[str, Any]:
"""
This method extends the ``clean()``-method to verify that a user can modify this content model
Expand Down
61 changes: 61 additions & 0 deletions integreat_cms/cms/models/abstract_content_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,67 @@ def path(self) -> str:
"""
return str(self)

@cached_property
def combined_text(self) -> str:
"""
The content this translation delivers, including any content embedded from elsewhere.

Only :class:`~integreat_cms.cms.models.pages.page_translation.PageTranslation` embeds
anything (the translation of its mirrored page), so for every other content type this
is just the content itself.

:return: The content to deliver, still containing shortcodes
"""
return self.content

@property
def content_for_cms(self) -> str:
"""
The content as it should be presented to users of the CMS, which means with all
shortcodes referencing internal content expanded into ordinary links.

Everything which is saved back through
:class:`~integreat_cms.cms.forms.custom_content_model_form.CustomContentModelForm`
is collapsed into shortcodes again.

This deliberately is not a :class:`~django.utils.functional.cached_property`:
:class:`~integreat_cms.cms.forms.custom_content_model_form.CustomContentModelForm`
reads it while initializing the form and then assigns the submitted content to the
very same instance, so a cached value would be the *previous* content by the time
the instance is saved.

:return: The content with expanded links
"""
# Imported here because the utils import the models
from ..utils.shortcodes import expand_shortcodes_for_cms

return expand_shortcodes_for_cms(self.content, self.language.slug)

def content_for_delivery(self, **extra_context: Any) -> str:
r"""
The content as it should be delivered by the API, which means with every shortcode
expanded into the representation of the object it references.

This is a method rather than a property because expanding a shortcode may need
context which cannot be derived from the translation, such as the current request.

:param \**extra_context: Additional context for the shortcodes, which takes
precedence over the context derived from this translation
:return: The expanded content
"""
# Imported here because the utils import the models
from ..utils.shortcodes import expand_shortcodes_for_delivery

return expand_shortcodes_for_delivery(
self.combined_text,
context={
"region_slug": self.foreign_object.region.slug,
"language_slug": self.language.slug,
"content_object": self,
**extra_context,
},
)

@cached_property
def hix_enabled(self) -> bool:
"""
Expand Down
2 changes: 1 addition & 1 deletion integreat_cms/cms/templates/content_versions.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ <h1>
<label>
{{ content_label }}
</label>
{{ translation.content|safe }}
{{ translation.content_for_cms|safe }}
</div>
<div class="revision-diff w-full p-4 mb-4 rounded border border-solid border-gray-200 shadow bg-white">
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@
<h1 class="font-default">
{{ diff.existing.title }}
</h1>
{{ diff.existing.content|safe }}
{{ diff.existing.content_for_cms|safe }}
</div>
<div class="xliff-import-target hidden">
<h1 class="font-default">
{{ diff.import.title }}
</h1>
{{ diff.import.content|safe }}
{{ diff.import.content_for_cms|safe }}
</div>
<div class="xliff-diff-preview-rendered {% if diff.existing.language.slug == 'zh' %} font-content-sc {% elif diff.right_to_left %} font-content-rtl text-right {% else %} font-content {% endif %}">
</div>
Expand Down
6 changes: 3 additions & 3 deletions integreat_cms/cms/templates/pages/page_pdf.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ <h1 id="title_page">
<h1 class="level-{{ page.depth|add:"-1" }}">{{ page_translation.title }}</h1>
<div class="content">
{% if page.mirrored_page_first %}
{{ page_translation.mirrored_translation_text|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{{ page_translation.mirrored_translation_text|expand_links:language.slug|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{% endif %}
{{ page_translation.content|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{{ page_translation.content_for_cms|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{% if not page.mirrored_page_first %}
{{ page_translation.mirrored_translation_text|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{{ page_translation.mirrored_translation_text|expand_links:language.slug|pdf_strip_fontstyles|pdf_truncate_links:80|safe }}
{% endif %}
</div>
{% for close in info.close %}
Expand Down
2 changes: 1 addition & 1 deletion integreat_cms/cms/templates/pois/poi_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ <h1>
{{ poi_translation.title }}
</h1>
<div class="pt-[30px]">
{{ poi_translation.content|safe }}
{{ poi_translation.content_for_cms|safe }}
</div>
{% endblock raw_content %}
Loading
Loading