Custom PagingNavigator for SEO friendly URL

Apache Wickets biggest strength is its focus on components - Among a very large set of components is PagingNavigator component. It is a Wicket Panel component to draw and maintain a complete page navigation. I found this component very useful but the only problem that compelled me to write my own CustomPagingNavigator is the wicket URLs that are being created by clicking the page links. 

The Java Part...
public class CustomPaginationLinksPanel<T> extends Panel{
  private static final long serialVersionUID = 10002L;
  /**Pageable List View to be displayed */
  private PageableListView<T> mainView;
  /** Max count of links  default  value = 5 */
  private int linksPerPage = 5;
  /** Page Number currently visible */
  private int  currPgNum;
    /** first page number */
  private int firstNum;
  /** last page number */
  private int lastNum;
  //Calculated on the basic of List size
  private int maxPages;
//Parameter name that will be displayed as a part of URL
  private String PAGINATOR_PARAM_NAME = "pg";
   
    private WebPage navigateToPage;
    private PageParameters parameters;
    
    public CustomPaginationLinksPanel(String id, String paginatorParamName, int linksPerPage, PageableListView<T> main, WebPage page) {
super(id);

this.linksPerPage = linksPerPage;
        this.navigateToPage = page;
        this.mainView = main;
        
        if(paginatorParamName != null && !paginatorParamName.isEmpty())
        PAGINATOR_PARAM_NAME = paginatorParamName;
        init();        
        gotoPage();
        initComponents();
  }

    private void init() {

    this.parameters = navigateToPage.getPageParameters();
    this.currPgNo parameters.getAsInteger(PAGINATOR_PARAM_NAME, 1);
    this.maxPages = mainView.getPageCount();
   
    int padding = linksPerPage / 2;
firstNumcurrPgNum - padding > 0  ? currPgNum - padding : 1;
lastNumcurrPgNum + padding <= maxPages ? currPgNum + padding : maxPages;

int temp_currLppCnt = (lastNum + 1) - firstNum
//Following code handles the boundary Condition
if(temp_currLppCnt< linksPerPage){
if(firstNum == 1 && lastNum < maxPages){
lastNum = lastNum + (linksPerPage - temp_currLppCnt  <= maxPages ? lastNum + (linksPerPage - temp_currLppCnt) : maxPages
}
else{
firstNum = firstNum - (linksPerPage - temp_currLppCnt) >= 1 ? firstNum - (linksPerPage - temp_currLppCnt) : 1; 
}
}
if(temp_currLppCnt linksPerPage)
lastNum = lastNum - 1;
   }

    private void initComponents() {

        // previous control static
        WebMarkupContainer prevStatic = new WebMarkupContainer("prev");
        prevStatic.setVisible(currPgNo > 1);
        prevStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAMEcurrPgNo - 1)));
        add(prevStatic);

        // next control static

        WebMarkupContainer nextStatic = new WebMarkupContainer("next");
        nextStatic.setVisible(currPgNo < maxPages);
        nextStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAMEcurrPgNo + 1)));
        add(nextStatic);

        add(createPaginationLinks("links"));

    }

    private Component createPaginationLinks(String id) {

        return new RefreshingView<Integer>(id) {
          private static final long serialVersionUID = 10011L;
            @Override
            public boolean isVisible() {
                return maxPages > 1;
            }
            @Override
            protected Iterator<IModel<Integer>> getItemModels() {
                List<Integer> list = new ArrayList<Integer>();
                for (int i = firstNum; i <= lastNum; i++) {
                    list.add(i);
                }
                return new ModelIteratorAdapter<Integer>(list.iterator()) {
                    @Override
                    protected IModel<Integer> model(Integer object) {
                        return new Model<Integer>(object);
                    }
                };
            }

            
@Override

            protected void populateItem(final Item<Integer> item) {   
                Integer obj = item.getModelObject();
                
                BookmarkablePageLink<WebPage> notCurrent = new BookmarkablePageLink<WebPage>("notCurrent", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAME, obj));
                notCurrent.setVisible(!(obj.equals(currPgNo)));
                notCurrent.add(new Label("number", item.getModel()).setRenderBodyOnly(true));
                item.add(notCurrent);
                 
                item.add(new Label("current", item.getModel()).setVisible(obj.equals(currPgNo)));

                item.setRenderBodyOnly(true);

            }
        };
    }

    private void gotoPage() {

        mainView.setList( mainView.getList().subList((currPgNo - 1) * 10, (currPgNo * 10) < mainView.getList().size() ? currPgNo * 10 : mainView.getList().size()));
    }
  private PageParameters addParam(PageParameters original, String key, Object value) {
        PageParameters result = (PageParameters)original.clone();
        result.put(key, value);
        return result;
    }
}    

Here is the markup...
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
  <body>
  <wicket:panel>
        <div class="pagination" >
            <span wicket:id="prev">
  <a href="#" class="link previous" wicket:id="link">&laquo; Prev</a>
  </span>
            <span wicket:id="links">
<a href="#" class="link" wicket:id="notCurrent">
                    <span wicket:id="number">[page number]</span>
                </a>
<a href="#" class="link active" wicket:id="current">[page number]</a>
</span>
            <span wicket:id="next">
<a href="#" class="link next" wicket:id="link">&nbsp;&nbsp; Next &raquo;</a>
</span>
</div>
</wicket:panel>
   </body>
</html>

And finally usage of the custom component...
...
add(new PageableListView<Post>("post", post, itemsPerPage) {
  private static final long serialVersionUID = 10025L;
  @Override
protected void populateItem(ListItem<Post> item) {
final Post p = item.getModelObject();
item.add(new ContextImage("image", p.getImageUrl()));
PageParameters parameters = new PageParameters();
    parameters.put(PARAM_POST_TITLE, p.getPostUrl());
Link<Void> ttlLnk = new BookmarkablePageLink<Void>("titleLink", PostPage.class, parameters);
ttlLnk .add(new Label("title", p.getTitle()));
item.add(ttlLnk);
}
});
 
add(new CustomPaginationLinksPanel<Post>("btmNavigator", null, 5, listView, this));
...


Comments

Popular posts from this blog

Importing / Indexing MySQL data into Solr

The Externalizable Interface