• Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Java and Wicket web development thoughts, tutorials, and tips

roman@coderdreams.com
Coder DreamsCoder Dreams
  • Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Self-contained Wicket Fragments

October 31, 2020 Posted by Roman Sery wicket No Comments

If you don’t use Wicket Fragments often, they are great for creating small components that are especially useful inside of lists. The thing that prevents them from being truly reusable in your application is that you have to duplicate the fragment markup in each component.

We can get around this limitation by creating a self-contained fragment that takes care of specifying its own markup. Then we can reuse them throughout our application without duplication.

HtmlFragment

The HtmlFragment class declares an abstract method getHtml() that implementations must provide.

public abstract class HtmlFragment extends Fragment implements IMarkupResourceStreamProvider, IMarkupCacheKeyProvider {
    private static final long serialVersionUID = 1L;

    public HtmlFragment(String id) {
        super(id, "", null);
    }

    protected abstract String getHtml();

    @Override
    protected IMarkupSourcingStrategy newMarkupSourcingStrategy() {
        return new PanelMarkupSourcingStrategy(false);
    }

    @Override
    public String getCacheKey(MarkupContainer container, Class<?> containerClass) {
        return containerClass.isAnonymousClass() ? containerClass.getSuperclass().getSimpleName() : containerClass.getSimpleName();
    }

    @Override
    public IResourceStream getMarkupResourceStream(MarkupContainer container, Class<?> containerClass) {
        String str = "<wicket:panel>" + getHtml() + "</wicket:panel>";
        return new StringResourceStream(str);
    }
}

It’s important to remember that if your specific fragment implementation has dynamic/conditional markup creation, you need to override the getCacheKey() method to handle that accordingly.

Let’s look at an example

Suppose you want a reusable fragment that displays the first and last names of a user. You could create a fragment extending HtmlFragment like so:

public class UserNameFragment extends HtmlFragment {
    private static final long serialVersionUID = 1L;

    public UserNameFragment(String id, IModel<User> userModel) {
        super(id);

        add(new Label("fname", new PropertyModel<>(userModel, "firstName")));
        add(new Label("lname", new PropertyModel<>(userModel, "lastName")));
    }

    @Override
    protected String getHtml() {
        return "<p>first name: <span wicket:id=\"fname\"></span></p>" +
                "<p>last name: <span wicket:id=\"lname\"></span></p>";
    }
}

In this case, our HTML is static, so we don’t need to modify the creation of the cache key.

Using it

Using UserNameFragment inside of a list of users is straightforward:

<span wicket:id="userList">
    <span wicket:id="nameFrag"></span>
</span>
public HtmlFragmentTestPage() {
    super();

    addOrReplace(new ListView<User>("userList", LoadableDetachableModel.of(this::getUsers)) {
        @Override
        protected void populateItem(ListItem<User> item) {
            item.addOrReplace(new UserNameFragment("nameFrag", item.getModel()));
        }
    });
}

private List<User> getUsers() {
    User u1 = new User(1, "John", "James", true);
    User u2 = new User(2, "Mike", "Jones", true);
    return List.of(u1, u2);
}

See the full working example here!

No Comments
Share
4

About Roman Sery

I've been a software developer for over 10 years and still loving Java!

You also might be interested in

Wicket quick tip #3: How to include templated Javascript files

May 3, 2020

A series of quick tips aimed at improving your productivity. How to create Javascript files with server-side injected values.

Customizing your codebase for each customer using Enumerations

Jul 26, 2019

Use enums and properties files to define all the behaviors of your application that are available for customization to your clients.

Using MySQL JSON columns to simplify your data storage: Part 1

Nov 28, 2019

Simplify data storage in your apps by using JSON column types instead of relying on database normalization.

Categories

  • aws
  • customization
  • database
  • debugging
  • enum
  • java
  • models
  • performance
  • projects
  • react
  • software design
  • Spring
  • tool
  • Uncategorized
  • wicket

Recent Posts

  • Rent Day
  • Self-contained Wicket Fragments
  • Pros and cons of unit testing
  • Themeable React Monopoly board
  • Please dont use client-specific release branches

Recent Comments

  • TCI Express Thanks for sharing such insightful information. TCI Express truly stands out as the best air logistics company, offering fast, secure, and efficient air express and cold chain transportation services....

    Tracking down a bug in production Wicket application ·  March 25, 2025

  • Tom Error: A zip file cannot include itself Can you please correct the plugin part so it doesn't use the same folder as input?

    Deploying Spring Boot app to AWS Beanstalk with Nginx customization ·  September 3, 2021

  • Golfman: Reality always wins I've used both Wicket and front-end JS frameworks and, having worked extensively on both, I can tell you that "Speed of development" is definitely NOT with the JS frameworks. You basically end up...

    Five reasons you should use Apache Wicket ·  August 29, 2021

  • Kiriller Sorry can not agree with you, wicket might be a well built technical framework. But the advantages of using a front-end framework like react.js and vue.js can not be beaten by Wicket nowadays. - Speed...

    Five reasons you should use Apache Wicket ·  August 23, 2021

  • Bernd Lauert Sorry but i have to refute your claims with the following arguments: 1. the Wicket community may be small but it is also very responsive, you usually get a helpful answer from the core devs on the...

    Five reasons you should use Apache Wicket ·  July 1, 2021

Archives

  • May 2021
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019

Contact Me

Send Message
Prev Next