Repository navigation
Assisted Templates - #20154
Assisted Templates#20154urbanit wants to merge 13 commits into
Conversation
A "Theme Templates" button next to "Add Template" lists the templates of the active site theme (or admin theme for Admin Templates), and of the themes it is based on, read from the theme's shape table. - Liquid templates can be cloned as local templates, reset to the theme template, or deleted, one by one or as bulk actions. - Razor templates are view only, with a "Create override" shortcut that opens the Add Template editor with the template name. - Cloned templates are monitored: the hash of the cloned content tells whether the local template was edited, and whether the theme template changed since. The list can be filtered by these statuses. - Templates are listed through ITemplateSource, so other sources, e.g. the templates of features, can be added as more buttons later. WIP: unit tests and the .pot translation template still to be verified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
The ancestor of the template source view now links back to the list, and OrchardCore.Templates.pot carries the strings of the Theme Templates pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
A dropdown of the Theme Templates list selects one of the site themes, or of the admin themes, the active theme by default, also when there is only one. The templates of a theme are read from its files and those of the themes it is based on, so themes that are not enabled can be listed too. The templates of a theme that is not active can only be viewed: a local template applies at once to the active theme, so cloning another theme's template would render the active theme with it. A local template is only compared to the file it was cloned from. After the active theme changes, the templates cloned from the previous theme show as "Cloned from" that theme, instead of as edited or changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
A Feature Templates button lists the templates of the enabled features, all of them by default, or those of the feature selected in the dropdown, which has a search box. They are almost all Razor templates, listed as a reference with Create override, which gives the shape name to override. - A template that is not the one rendering its shape shows "Overridden by" the active theme or the feature whose template wins, read from the shape table of the active theme. - A "Renders" filter splits front end and admin templates, guessed from the words of their names (Edit, SummaryAdmin, Design, Deployment...): front end on Templates and admin on Admin Templates by default. - Each template source describes its list, and the first scope is the default one, e.g. the active theme or all the features. - The source buttons and the scope dropdown share one row of the action bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
Alternates: an Alternates button on the templates of the Theme and Feature Templates lists shows the alternates of their shape for the content types of the site, from the content items (Content, or the stereotype, e.g. Widget), their parts and their fields, in Detail and Summary, or in DetailAdmin and SummaryAdmin for the admin templates. The part and field alternates come from ContentPartAlternatesFactory and ContentFieldAlternatesFactory, so they match those the drivers add. Each alternate tells whether a local template or the theme has it, and can be created, cloned from a Liquid template of the active theme, or viewed when the theme already renders it. Modules can suggest other alternates with an ITemplateAlternatesProvider. Inspect Content: from the templates lists, or the actions of a content item, renders a content item in a display type while recording the shapes it renders, then shows them as a tree with the template rendering each of them, resolved with the site theme and the templates (or the admin theme and the admin templates) the way the display manager resolves them, and all their alternates, including those of the content item only. ActiveThemes gives the active site or admin theme to the sources, the alternates and the inspection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
The Inspect Content page lists View and Clone actions next to the template of the active theme or of a feature that renders a shape or is bound to one of its alternates, on the site and on the admin. Add Template is the primary button of the templates lists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
The Theme and Feature Templates lists, the alternates and Inspect Content are part of the new OrchardCore.Templates.Assisted feature of the Templates module, which is not enabled by default. The Templates and Admin Templates lists only show their buttons when it is enabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
The Theme Templates and Feature Templates lists filter their templates by language, Liquid or Razor. The page viewing a template only shows its Alternates button when its shape has alternates, like the lists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
- Forget the clone record of a template deleted, renamed or bulk deleted from the Templates lists, so a template written later with its name isn't taken for a clone. - Keep the inspected content item in the picker when it's older than the recent ones, build its display inside the error handling, and write the indentation of the shapes with the invariant culture. - Show the alternates generated for every display type as applying to all of them. - Describe a template cloned from another source's file without guessing it was a theme active before. - Return 404 when deleting an override without a name. - Use collection expressions and document the public view models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
|
Can you put a link to the youtube video at the correct timestamp to recall what the feature was about? |
|
https://youtu.be/4nIjSBtQgx0?si=WVi8bbg1Q2aDidCC&t=2683 original discussion is here: https://github.com/orgs/OrchardCMS/discussions/19709 I will update the same discussion with new implementation |
|
Discussion updated with comment: https://github.com/orgs/OrchardCMS/discussions/19709#discussioncomment-19274871 |
|
This pull request has merge conflicts. Please resolve those before requesting a review. |
|
Hi @urbanit — I ran this PR through an automated review harness and two issues surfaced:
Full line-by-line breakdown: |
- The new OrchardCore.Templates.ShapeTracing feature, which depends on OrchardCore.Contents, holds what needs the content services: Inspect Content, the Inspect templates action of the content items and the alternates suggested for the content types. Assisted Templates only depends on Templates, so its template sources work without Contents. - The picker of the inspector only lists the content items the user can view, checking ViewContent on each of them, and has a search box filtering them by their display text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
|
Thanks for the review @grandua, both were real. Fixed in d946efd: Picker authorizationThe inspector’s picker now only lists content items the user can view (ViewContent on each item), paging through the latest items until it has 50, and has a search box to find older ones by display text. I looked at reusing the Content Picker, but its search endpoint returns every match and only flags whether each one is viewable, so it wouldn’t have closed the gap. Contents dependencyEverything that needs the content services moved to a new OrchardCore.Templates.ShapeTracing feature that depends on OrchardCore.Contents: Inspect Content, the Inspect templates action and the content-type alternates provider. That provider also fed the Theme/Feature Templates lists, so those pages failed without Contents too. Assisted Templates now only depends on Templates, and a functional test checks its pages on a tenant without Contents (the SaaS recipe). |
- The inspector picks its content item with the content picker of the content picker fields, searching the content items as you type, so Shape Tracing depends on OrchardCore.ContentFields. - A content item is listed and inspected in its published version when it has one. A draft that was never published requires PreviewContent too, and is shown as not published. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117DzPPRjTuatDtobb9oDKj
|
Content picker UI The picker’s search box and select are replaced by the content picker of the content picker fields, the same component, searching as you type. It queries its own endpoint, TemplateInspector/SearchContentItems, which applies the same authorization, so it doesn’t use the content picker’s search endpoint mentioned above. Because of this, Shape Tracing also depends on OrchardCore.ContentFields. Drafts A content item is now listed, and inspected, in its published version when it has one, with ViewContent. A draft that was never published also requires PreviewContent, and is shown as not published. The same check applies when a content item is opened by its id in the URL. Without it, every signed-in user could see the titles of drafts, since the Authenticated role grants ViewContent by default. Tests The functional test now checks the content picker and its search endpoint. Checked manually with a role without PreviewContent: a draft is neither listed nor inspectable by its id, and it is listed, as not published, once the role can preview content. |
-Thanks for the quick turnaround, @urbanit — I've re-run the automated Verdict: your authorization fix no longer shows up in the findings, Heads-up: this pass covers head d946efd — anything pushed after it |
Adds an opt-in Assisted Templates feature (
OrchardCore.Templates.Assisted) to the Templates module. It helps editors find, view and override the shape templates of the themes and features from the Templates and Admin Templates pages, without opening the source code.What it adds
When the feature is enabled, the Templates list (and the Admin Templates list when that feature is enabled) gets these buttons:
Content__Alias__[Alias],Content__Slug__[Slug]). The template rendering a shape, or matching an alternate, can be viewed and, if it's Liquid, cloned from there.Modules can list the templates of other extensions by registering an
ITemplateSource, and suggest alternates with anITemplateAlternatesProvider.Also in this PR: Add Template is the primary button of the templates lists.
The feature is documented in the Templates module docs (Assisted Templates section) and in the 4.0.0 release notes.
Known limitations
These came up in review. They are design-level, so I left them for follow-up rather than widening this PR:
placement.json(hidden shapes, extra alternates) isn't reflected. Shapes a site theme template renders in its own markup aren't listed (the page says so).BasicShapeTemplateHarvesterdoes, in a copy of its logic. Sharing a case-preserving helper would need a change outside the module.Testing
test/OrchardCore.Tests/Modules/OrchardCore.Templates): template sources, clone monitoring, alternates, shape inspection and authorization (47 tests).AssistedTemplatesTestschecks that the buttons, pages and content item action are absent until the feature is enabled, and present afterwards.AdminListLayoutTestsnow enables the feature and renders the Theme Templates, Feature Templates and Alternates lists as grids.