wicket-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thibault Kruse <tibokr...@googlemail.com>
Subject Re: Programmatic Markup with fallback
Date Tue, 16 Sep 2014 13:59:28 GMT
I realize now using the wicket:panel tag only works with panels, so
maybe the wicket way to go would be to have a "raw" markup file
without the xmlns declaration. I don't know. In any case, I preferred
to use a panel with a "complete" html file like for any other panel,
so I had to circumvent the PanelMarkupSourcingStrategy from overruling
getMarkup().

In the implementation below I also preferred to use setMarkup() over
overriding getMarkup(). It seems to me getMarkup() is not suitable to
be overwritten, as the rest of the code with Component seems to assume
it is an accessor to a field (hence multiple invocations are assumed
cheap. The last invocation I listed was just used to get a handle to
the MarkupStream). I would recommend making getMarkup() final, and
maybe change the javadoc comment in IMarkupResourceStreamProvider.

I tried to get a IMarkupResourceStreamProvider solution to work, but I
fail to see an obvious way to get the associated Markup of a panel
class implementing IMarkupResourceStreamProvider, all approaches I
tried ended up using the provided getMarkupResourceStream() method.


public class CustomMarkupFallback2MarkupContainer extends
GenericPanel<String> implements IMarkupCacheKeyProvider {
    private boolean overrideMarkup = false;
    public CustomMarkupFallback2MarkupContainer(String id, String
markupString) {
        super(id);
        if (markupString != null) {
            setMarkup(Markup.of(markupString));
            overrideMarkup = true;
        }
    }

    /**
     * For panels, the strategy by Panel.newMarkupSourcingStrategy()
overrules markup, reads associated markup in the end
     * @return
     */
    protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
    {
        if (overrideMarkup) {
            return DefaultMarkupSourcingStrategy.get();
        }
        return super.newMarkupSourcingStrategy();
    }

    /**
     * Do not cache markup by wicket, null means no caching. must
implement IMarkupCacheKeyProvider
     */
    @Override
    public String getCacheKey(MarkupContainer container, Class<?>
containerClass) {
        return null;
    }
}

On Tue, Sep 16, 2014 at 2:28 PM, Thibault Kruse
<tibokruse@googlemail.com> wrote:
> I forgot to mention, for my solution to work, the associated markup
> file must not have tags outside the wicket:panel tags:
> <wicket:panel>
>     Fallback works!
> </wicket:panel>
>
> as opposed to
>
> <?xml version="1.0" encoding="UTF-8"?>
> <html xmlns="http://www.w3.org/1999/xhtml"
> xmlns:wicket="http://wicket.apache.org">
> <body>
> <wicket:panel>
>         Fallback works!
> </wicket:panel>
> </body>
> </html>
>
> So I guess I am still doing something wrong here.
>
> On Tue, Sep 16, 2014 at 12:28 PM, Thibault Kruse
> <tibokruse@googlemail.com> wrote:
>> So, I have a working solution like this:
>>
>> public class CustomMarkupFallbackMarkupContainer extends
>> WebMarkupContainer implements IMarkupCacheKeyProvider {
>>     public CustomMarkupFallbackMarkupContainer(String id,
>> IModel<String> model) {super(id, model);}
>>
>>     @Override
>>     public IMarkupFragment getMarkup() {
>>         String markupString = (String) getDefaultModelObject();
>>         if (markupString == null) {
>>             return getAssociatedMarkup();
>>         } else {
>>             return Markup.of(markupString);
>>         }
>>     }
>>
>>     @Override public String getCacheKey(MarkupContainer container,
>> Class<?> containerClass) {return null;}
>> }
>>
>> Regarding the multiple invocations of getMarkup(), they also occur
>> when caching, and indeed they occur on every request (caching happens
>> only for the associated markup, I assume). The calls all happen inside
>> the same call to Component.internalRender()
>>
>> Invocations are:
>> 1: Component.internalRender():2309 // creating a MarkupStream only
>> used inside if block
>>
>> 2:
>> Component.internalRenderComponent():2472 // some duplicate code with
>> internalRender()
>> MarkupContainer.onRender(): 1496
>> Component.internalRender():2344
>>
>> 3:
>> Component.renderComponentTag():3961
>> Component.internalRenderComponent():2505
>> MarkupContainer.onRender(): 1496
>> Component.internalRender():2344
>>
>> 4:
>> Component.renderComponentTag():3961
>> AssociatedMarkupSourcingStrategy.renderAssociatedMarkup()
>> AssociatedMarkupSourcingStrategy.renderAssociatedMarkup()
>> PanelMarkupSourcingStrategy.onComponentTagBody():112
>> Component.internalRenderComponent():2514
>> MarkupContainer.onRender(): 1496
>> Component.internalRender():2344
>>
>>
>>
>> Regarding usage of onComponentTagBody(), that seems also valid, but
>> much deeper into the Wicket API than I would want to go, in particular
>> given there are recommended solutions in
>> http://wicket.apache.org/guide/guide/advanced.html#advanced_5 and the
>> javadoc.
>>
>> On Tue, Sep 16, 2014 at 12:00 PM, Andrea Del Bene <an.delbene@gmail.com> wrote:
>>> Hi,
>>>
>>> I didn't dig to much into the code, but keep in mind that you are disabling
>>> markup caching in your example. This might explain why getMarkup is called
>>> three times.
>>> Anyway, in your specific case it might be better not to implement
>>> IMarkupCacheKeyProvider and IMarkupResourceStreamProvider, but simply
>>> override onComponentTagBody like this:
>>>
>>> @Override
>>>     public void onComponentTagBody(MarkupStream markupStream, ComponentTag
>>> openTag) {
>>>         if (getDefaultModelObject() == null) {
>>>             super.onComponentTagBody(markupStream, openTag);
>>>         }
>>>         else {
>>>
>>>             replaceComponentTagBody(markupStream, openTag, "<wicket:panel>it
>>> works</wicket:panel>");
>>>         }
>>>     }
>>>>
>>>> So debugging a bit, I find that I get hit by the
>>>> PanelMarkupSourcingStrategy. It seems it throws away the body markup
>>>> in favcor of the associated Markup. So I could advance one step by
>>>> extending WebMarkupContainer instead of Panel.
>>>>
>>>> I notice that when extending Panel, getMarkup() is being called 3
>>>> times in my example, before the result is being discarded.
>>>>
>>>> That seems like design smell. If users override getMarkup() with some
>>>> expensive operation, they should be able to rely on this being called
>>>> just once, and this only if the result is actually being used.
>>>>
>>>> On Tue, Sep 16, 2014 at 11:24 AM, Thibault Kruse
>>>> <tibokruse@googlemail.com> wrote:
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Mime
View raw message