Some macros use List Formatter for printing a list of Users, Snips and other things. SnipSnap ships with e.g. AtoZ, Vertical and Simple list formatters.
Formatters can then be used by macros which support formatters to change the look of the list, for example {index} takes a formatter to display all files.
Usually the index page contains {index:AtoZ} which tells the index macro to use the AtoZ formatter. This tutorial tells you how to design your own output format.
To write your own list formatter you have to implement org.snipsnap.snip.filter.macro.list.ListFormatter, especially the method
public void format(Writer writer,
String listComment,
Collection c,
String emptyText,
boolean showSize)
throws IOException;Writer is of Type
java.io.Writer and is used to write your output to the html page. A formatter object should output HTML. The
listComment is an explaination given to the users, like "SnipSnap users", c is of type
java.util.Collection collection and contains the objects you want to display, e.g. search results, snip lists, user lists etc.
EmptyText is usually displayed when the collection c is empty, like "No users." and if
showSize is true, then your formatter should show the number of objects in the collection.
Example
A very simple formatter would display a numbered list of the snips.
public void format(Writer writer, String listComment,
Collection c, String emptyText,
boolean showSize)
throws IOException {
if (c.size() > 0) {
writer.write("<ol>");
Iterator nameIterator = c.iterator();
while (nameIterator.hasNext()) {
writer.write("<li>");
Object object = nameIterator.next();
if(object instanceof Snip) {
SnipLink.appendLink(writer, ((Snip)object).getName());
}
writer.write("</li>");
}
writer.write("</ol>");
} else {
writer.write(emptyText);
}
}The formatter takes the collection and iterates over it. Then it takes a look at the object and when the object is of type Snip, a link to the snip with the name of the snip is written. This formatter could only be used with a collection of snips. To make it more useful, you could use the interfaces
Nameable and
Linkable. Snips for example implement Nameable.
if(object instanceof Linkable) {
writer.write(((Linkable)object).getLink());
} else if(object instanceof Nameable) {
SnipLink.appendLink(writer, ((Nameable)object).getName());
} else {
writer.write(object.toString());
}
Full example
To make your formatter fit more into SnipSnap, it's a good idea to use CSS.
An example could look like this:
public void format(Writer writer, String listComment,
Collection c, String emptyText,
boolean showSize)
throws IOException {
writer.write("<div class=\"list\"><div class=\"list-title\">");
writer.write(listComment);
if (showSize) {
writer.write(" (");
writer.write("" + c.size());
writer.write(")");
}
writer.write("</div>");
…
writer.write("</div>");
}There is an ExampleListFormatter distributed with the source of SnipSnap.
Deployment
To now use your list formatter you have to first give your list formatter a name. We take "number" for this
one. Add a
getName method to the formatter:
public String getName() {
return "number";
} so you can call the macro with {hello} from a snip.
Create a jar file with
META-INF/services/org.snipsnap.snip.filter.macro.list.ListFormatter
example/ExampleListFormatter.class
META-INF/services/org.snipsnap.snip.filter.macro.list.ListFormatter should contain lines with the class names
of your macros, for example
example.ExampleListFormatter
Put this jar into
applications/<AppName>/WEB-INF/lib for example if your application is named
MyBlog then
applications/MyBlog/WEB-INF/lib. Restart the server and the formatter should work. You can test this when you use the formatter with {index:number} instead of the AtoZ formatter.
List Formatter Tutorial 2 explains how to use a ListFormatter with your own macros.