Lukasz Lenart created WW-5768:
---------------------------------

             Summary: Make struts.ui.theme and struts.ui.templateDir scopable 
per package
                 Key: WW-5768
                 URL: https://issues.apache.org/jira/browse/WW-5768
             Project: Struts 2
          Issue Type: Improvement
          Components: Core Tags
            Reporter: Lukasz Lenart
             Fix For: 7.5.0


The first adopter of package-scoped constants 
([WW-3476|https://issues.apache.org/jira/browse/WW-3476]). That change shipped 
the mechanism only, and no constant is scopable yet, so any 
{{<scoped-constant>}} currently fails at startup.

h2. Goal

Allow a package to override the default UI theme and template directory:

{code:xml}<package name="admin" extends="struts-default" namespace="/admin">
    <scoped-constant name="struts.ui.theme" value="css_xhtml"/>
    <scoped-constant name="struts.ui.templateDir" value="admin-template"/>
    ...
</package>
{code}

Child packages inherit the override through {{extends}}. Today the same effect 
needs a {{theme}} attribute on every tag, or an interceptor that puts {{theme}} 
into the request scope.

h2. Why these two constants

{{UIBean.getTheme()}} and {{UIBean.getTemplateDir()}} resolve their values when 
a tag renders, inside the result, so the action invocation and its package are 
known. The injected global value is only the last step of an existing chain:
# the tag attribute
# the enclosing form (theme only)
# the request / session / application {{theme}} / {{templateDir}} attribute
# the injected {{defaultUITheme}} / {{defaultTemplateDir}}

Only step 4 changes. Everything users rely on today keeps its precedence.

h2. Proposed change
* Register a {{ScopableConstants}} bean in {{struts-beans.xml}} (for example 
{{StrutsUiScopableConstants}}) that returns {{struts.ui.theme}} and 
{{struts.ui.templateDir}}.
* Inject {{ScopedConstantProvider}} into {{UIBean}}, and in step 4 use 
{{scopedConstantProvider.getValue(...)}} instead of the injected field. The 
provider already falls back to the global constant when there is no invocation 
(a JSP rendered without an action) or no override.
* Register the bean in {{StrutsDefaultConfigurationProvider}} too, for the test 
harness.

h2. Tests
* A package override is used when the tag has no {{theme}} / {{templateDir}}.
* The tag attribute, the enclosing form's theme, and a request-scope {{theme}} 
attribute still win over the override.
* A child package inherits the parent's override.
* With no invocation, or no override, the global constant is used.
* The previously rejected {{<scoped-constant name="struts.ui.theme">}} now 
loads, and an unrelated name is still rejected at startup.

h2. Docs

Update the struts-site page for scoped constants ({{package-configuration.md}}, 
see struts-site PR #351) to list these two as the scopable constants, and 
mention the override in the themes and templates page.

h2. Out of scope
* {{struts.ui.theme.expansion.token}} and {{struts.ui.staticContentPath}}
* {{struts.convention.result.path}}: it is read at startup by 
{{DefaultResultMapBuilder}}, when there is no invocation, so it needs a lookup 
by package name. That is a separate ticket.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to