Blogs
I recently had the realization that I was duplicating a certain set of code across multiple portlets. For those who know me, they will attest that my work motto is to work smart not hard. I hate code duplication with a fiery passion, thus something had to be done. The question was what? After some thought, I decided that I needed to make a taglib. I started coding it, and had a realization... a tagfile would be much easier!
So what is a tagfile? Tagfiles were introduced with JSP 2.0. They were created because sometimes a taglib is jsut too much work for what it does. For many simple and even some complex operations, tagfiles are like coding magic. Let's compare the two:
- Taglibs:
- Class driven
- Uses a tld that can be from any site
- JSP 1.1 compatible.
- Tagfiles
- JSP driven
- No tld required
- Works immediately without any compile
- Really easy!
So if you can't guess, I chose to use a tagfile. Before I show you the code, let's do a high level overview of what is required for tagfiles.
- You
- A tags folder under WEB-INF (/WEB-INF/tags)
- A folder under that with the name of the tag
- a .tag file
So lets make a basic Hello World tagfile that outputs the text "Hello World in (Insert Year Here)".
Step 1: create /WEB-INF/tags/hello-world/hello.tag
Step 2: enter the following in hello.tag:
<%@attribute name="year" required="true"%>
Hello World in <%=year%>
Step 3: Edit your JSP that you want the hello world to show up in. Enter this code:
<%@ taglib prefix="showMore" tagdir="/WEB-INF/tags/hello-world" %>
<showMore:hello />
That should be all that's required. Refresh your jsp. Eat cake.
So sure, that's cool and all... but you could EASILY accomplish the same this with a simple file include. Where is the excitement? The drama? It's right here, you just don't know it yet.
Let's do a more useful example. Let's say that you hate using our <portlet:actionURL /> taglib... you want something easier and cleaner. I know in my IDE it always breaks my <a href's /> when I put it in. Time to fix that. This tagfile will do the following: create a Struts url (maximized or minimized) to a struts path, if a clean way that IDEs understand.
Step 1: create init.tag under hello-world
Step 2: enter the following in init.tag
<%@ tag import="com.liferay.portal.kernel.security.permission.ActionKeys" %>
<%@ tag import="com.liferay.portal.kernel.util.StringPool" %>
<%@ tag import="com.liferay.portal.service.permission.PortletPermissionUtil" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-nested" prefix="nested" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %>
<%@ tag import="com.liferay.portal.util.PortalUtil" %>
<%@ tag import="com.liferay.portal.util.PortletKeys" %>
<%@ tag import="javax.portlet.WindowState" %>
<%@ tag import="java.text.DateFormat" %>
<%@ tag import="java.util.List" %><%@attribute name="maximized" type="java.lang.Boolean"%>
<%@attribute name="struts_path" required="true" %>
<%@attribute name="actionUrl" type="java.lang.Boolean"%>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<%
String currentURL = PortalUtil.getCurrentURL(request);
%>
Notice that this looks a lot like a regular liferay init.jsp... that's because it almost is! We just replace <%@page %> with <%@tag %>.
Step 3: edit hello.tag with the following code:
<%@include file="init.tag"%>
<%
String windowState=null;
if (maximized != null) {
windowState = WindowState.MAXIMIZED.toString();
}
else {
windowState = WindowState.NORMAL.toString();
}
%>
<%
if (actionUrl != null) {
%>
<portlet:actionURL windowState="<%=windowState%>">
<portlet:param name="struts_action" value="<%=struts_path%>" />
</portlet:actionURL>
<%
}
else {
%>
<portlet:renderURL windowState="<%=windowState%>">
<portlet:param name="struts_action" value="<%=struts_path%>" />
</portlet:renderURL>
<%
}
%>
Step 4: Lastly, enter this into your jsp.
<showMore:hello struts_path="/a/view" maximized="true" actionUrl="true"/>
Take note that your struts path will change, and that struts_path is the only one required...
Step 5: Reload your page, enjoy your beautiful link.
Step 6: Enjoy more cake.