Custom tags are cool, I guess. The first couple I wrote were fun to write. Kind of like driving through a new city, or part of the country. The landscape is vibrant, new, unfamiliar, exciting. When I came back several months later, things were just unfamiliar, and not so exciting.
If you are taking the OCEJWCD test, there is no avoiding them. However, my recommendation is, unless you are writing a Servlet framework, avoid them. Unless you are writing them with enough frequency to remember the necessary semantics to their creation, the API, it will be a constant battle to remember what all that "stuff" does and means.
<%@tag body-content="empty" isELIgnored="false" display-name="KingCrimson" %>
<%@tag import="java.text.MessageFormat" %>
<%@ attribute name="uname" rtexprvalue="true" required="true" type="java.lang.String" %>
<%@ attribute name="album" rtexprvalue="true" required="true" type="java.lang.String" %>
<%@ attribute name="song" rtexprvalue="true" required="true" type="java.lang.String" %>
<%
String uname = (String) jspContext.getAttribute("uname");
String album = (String) jspContext.getAttribute("album");
String song = (String) jspContext.getAttribute("song");
MessageFormat form = new MessageFormat("{0}'s favorite King Crimson song is\"{2}\" from the Album {1}.");
jspContext.setAttribute("message", form.format( new Object[] {uname, album, song } ) );
%>${message}
You can immediately see that the bar to development, maintenance, and readability has been dramatically lowered. I will leave it as an example for yourself to develop this as a custom tag. You tell me which is easier.
In your OSGi bundle project, in the src/main directory you need to create a 'resources' folder, and beneath that create a 'META-INF' folder. Within META-INF create a text file called: taglib.tld. Here is a sample tld file for our King Crimson tag file: taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.
See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>Our Custom Tagfiles</description>
<tlib-version>1.0</tlib-version>
<short-name>OurCustomTagfiles</short-name>
<uri>https://www.yoursite.com/taglibs/cq5/custom/1.0</uri>
<tag-file>
<name>kcfavsong</name>
<path>/META-INF/tags/kcfavsong.tag</path>
</tag>
</taglib>
The name portion in the <tag-file> section is the name you will be using to refer to the tag-file when you use it. More on that in the example usage. The path is exactly what you think, where it's located.
Beneath the META-INF directory, you will create a 'tags' directory, and put the tag file from above in that directory.
Because I have been implementing this in the same manner using the maven bundle plugin for 4 or 5 years now, I am not completely sure if the following metadata within the definition of the maven bundle plugin, are necessary. You could try leaving it out and see what happens. It will either work or it won't. If it doesn't, put it back in. If when leaving it out it still works, leave it out. But I define the following within the <instructions> section of the plugin configuration:
<Bundle-Resource>/META-INF/tags</Bundle-Resource>
<Sling-Bundle-Resource>/META-INF/tags</Sling-Bundle-Resource>
I apologize for this. It has always just worked this way, so I have never taken the time to attempt to remove any potential redundancy in the configuration of the plugin. But it does work when defining this metadata.
That is all thats needed from the development side of things. Now we need to deploy and simply use it.
The usage for this is:
<%@taglib prefix="custom" uri="https://www.yoursite.com/taglibs/cq5/custom/1.0" %>
<custom:kcfavsong uname="mjkelleher" song="SUPERBOTTOMFEEDER" album="Heaven and Earth" />
In a subsequent post, I will build upon this foundation to add a custom EL function to our taglib. I will show you one particular approach to using a Singleton Facade to manage many custom EL functions in a maintainable manner.