Skip to content

Conversation

@wesleyboar
Copy link
Member

@wesleyboar wesleyboar commented Feb 11, 2026

Overview

Allow CMS Admin (and only CMS admin) to change header logo.

Important

Related

Changes

  • feat: only cms admin edit static placeholder e2f7c53
  • feat: add 'header-logo' placeholder f52b8b2

Testing

Testing

  1. Backwards Compatibility
    With no content in the header-logo static placeholder, the site header still shows the logo from settings (LOGO or PORTAL_LOGO).

  2. Superuser – Header Logo
    As a superuser, open the CMS and edit the header-logo static placeholder. Add one Picture, set its template to "Header logo", set image and optional link. Save/publish. The header shows the custom logo and link.

  3. Superuser – Footer
    As a superuser, confirm the footer-content static placeholder is still editable and renders as before.

  4. Non-Superuser
    As a staff user who is not a superuser (e.g. in an editor group), confirm you cannot edit static placeholders (no header-logo or footer-content in the expected place, or no edit UI). The header still shows the settings-driven logo.

  5. Placeholder Limits
    As superuser on header-logo, confirm you can add only one plugin and that only "Picture" (or the configured "Picture" plugin) is offered.

  6. Permissions After Deploy
    Run the management command that applies group permissions (e.g. set_group_perms or the one that calls let_view_page_and_structure). Then re-check step 4: editor groups still cannot edit static placeholders.

UI

Copy link
Member Author

@wesleyboar wesleyboar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked AI to review how to improve clarity:

AI Suggestions

1. header_logo.html — > Name the three sources

The @var and the three > branches don’t say where each > source comes from. A short > comment per branch helps:

  • After the load/var block, > add a single line describing > the three cases, e.g.
    {# Logo source: plugin_logo > (CMS Picture), settings.LOGO > (legacy), or settings.> PORTAL_LOGO. #}
  • Or add a one-line comment > above each of the three > blocks, e.g.
    {# 1. From CMS static > placeholder "header-logo" > (Picture plugin). #}
    {# 2. From settings.LOGO > (legacy tuple). #}
    {# 3. From settings.> PORTAL_LOGO (default). #}

That makes it obvious why > there are three branches and > what each represents.


2. header_logo.html — > Document expected shape of > plugin_logo

The first and third branches > use the same logo.* keys. To > make the contract explicit for > someone editing the tag or the > template, add a short comment > near the top, e.g.:

  • {# plugin_logo (when set) > must provide: link_href, > link_target, img_class, > img_file_src, is_remote, > img_crossorigin, img_alt_text > (same shape as PORTAL_LOGO). #}>

Then it’s clear that > plugin_logo is “a > PORTAL_LOGO-shaped dict.”


3. header_logo_tags.py > — Document the contract and > simplify alt

  • In the docstring, state that > the returned dict is > PORTAL_LOGO-shaped (or > “same keys as header_logo.html > expects for the plugin_logo / > PORTAL_LOGO branch”). That > ties the tag to the template > without reading both.

  • Build alt in two steps so > the fallback chain is easier > to read:

    • alt_from_attrs = (getattr> (instance, 'attributes', > None) or {}).get('alt')
    • alt = alt_from_attrs or > (getattr(picture, > 'default_alt_text', None) if > picture else None) or ''

    Same behavior, but the > intent (“attribute alt, then > picture default, then > empty”) is obvious.

  • Optionally add a one-line > comment above the return > { ... }: e.g. “Same keys as > header_logo.html expects > (PORTAL_LOGO shape).”


4. header_logo_tags.py > — Clarify “instance”

  • In the docstring, spell out > that instance is the > djangocms_picture plugin > instance (the one that has > picture, attributes, > link_target, and provides > img_src in context). That > way “instance” isn’t ambiguous.

5. picture.html — > Optional one-line “why”

The comment already says “pass > plugin_logo and use shared > header_logo.html.” If you want > the reason in one line, you > could add:

  • {# Single markup in > header_logo.html; we only > supply plugin_logo from the > Picture plugin. #}

Summary

  • Templates: Name the > three logo sources (plugin / > LOGO / PORTAL_LOGO) and > document the expected > plugin_logo shape (same as > PORTAL_LOGO).
  • Tag: Docstring = “builds > a PORTAL_LOGO-shaped dict from > the Picture plugin instance”; > simplify alt with one or two > intermediate variables; > optionally a one-line comment > above the returned dict.

That should make the flow (Picture → tag → plugin_logo → header_logo.html’s first branch) and the data contract clear for the next reader.

@wesleyboar
Copy link
Member Author

I do not yet unite all three ways to build a header logo, because this PR is clear and clean and isolated without refactor. Refactor can be done in isolation after this PR is tested and merged.

@wesleyboar wesleyboar marked this pull request as ready for review February 11, 2026 18:55
@wesleyboar wesleyboar marked this pull request as draft February 11, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant