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...
Here is the markup...
And finally usage of the custom component...
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;
firstNum = currPgNum - padding > 0 ? currPgNum - padding : 1;
lastNum = currPgNum + 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(parameters, PAGINATOR_PARAM_NAME, currPgNo - 1)));
add(prevStatic);
// next control static
WebMarkupContainer nextStatic = new WebMarkupContainer("next");
nextStatic.setVisible(currPgNo < maxPages);
nextStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parameters, PAGINATOR_PARAM_NAME, currPgNo + 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(parameters, PAGINATOR_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;
}
}
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;
firstNum = currPgNum - padding > 0 ? currPgNum - padding : 1;
lastNum = currPgNum + 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(parameters, PAGINATOR_PARAM_NAME, currPgNo - 1)));
add(prevStatic);
// next control static
WebMarkupContainer nextStatic = new WebMarkupContainer("next");
nextStatic.setVisible(currPgNo < maxPages);
nextStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parameters, PAGINATOR_PARAM_NAME, currPgNo + 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(parameters, PAGINATOR_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">« 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"> Next »</a>
</span>
</div>
</wicket:panel>
</body>
</html>
<body>
<wicket:panel>
<div class="pagination" >
<span wicket:id="prev">
<a href="#" class="link previous" wicket:id="link">« 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"> Next »</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));
...
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
Post a Comment