How to create a Blog in Portofino 4 - part 3
In the first tutorial we used Portofino 4 to create the blog data model and to create the main pages. In the second tutorial we introduced the permissions and changed the layout. For these operations, we used mainly Portofino out of the box via the web interface.
Step 1. Change the layout of the list for Posts
//******************************************************* // List objects //******************************************************* @DefaultHandler @Override public Resolution execute() { if (object == null) { return doList(); } else { return read(); } } public Resolution doList(){ firstResult = 0; maxResults= 10; loadObjects(); return forwardToPortletPage("/apps/default/web/listPosts.jsp"); }
<%@ page import="com.google.inject.internal.Objects" %> <%@ page import="java.util.List" %> <%@ page import="java.util.HashMap" %> <%@ page import="com.manydesigns.elements.xml.XhtmlBuffer" %> <%@ page import="org.apache.commons.lang.StringUtils" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes-dynattr.tld"%> <%@taglib prefix="mde" uri="/manydesigns-elements"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="portofino" %> <stripes:layout-render name="/skins/${skin}/portlet.jsp"> <jsp:useBean id="actionBean" scope="request" type="com.manydesigns.portofino.pageactions.crud.CrudAction"/> <stripes:layout-component name="portletTitle"> <c:out value="${actionBean.crudConfiguration.searchTitle}"/> </stripes:layout-component> <stripes:layout-component name="portletBody"> <div id="posts" > <portofino:buttons list="crud-search" cssClass="portletButton" /> <% XhtmlBuffer buffer = new XhtmlBuffer(); int i = 0; for (HashMap object : (List<HashMap>)actionBean.objects){ buffer.writeH2((String)object.get("title")); buffer.write(StringUtils.abbreviate( (String) object.get("summary"),300)); buffer.writeBr(); buffer.writeAnchor("post/"+object.get("id"), "Read"); buffer.writeHr(); i++; if(i==10) break; } out.println(buffer.toString()); %> </div> <script type="text/javascript"> result = 10; isLoading=false; $(window).scroll(function () { if ($(window).scrollTop() + $(window).height() > $('#posts').height() - 5 && !isLoading ) { isLoading = true; $.ajax({ type: 'GET', url: "post?jsonSearchData=1&firstResult="+ result+"&maxResults=10", contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { for (var i = 0; i < msg.Result.length; i++) {
$("div#posts").append('<h2>'+ msg.Result[i].title.value+ '</h2>'+msg.Result[i].summary.value+'<br/>'+ '<a href="post/'+msg.Result[i].id.value+ '">Read</a><hr/>'); } isLoading = false; } }); result = result+10; } }); </script> <portofino:buttons list="crud-search" cssClass="portletButton" /> </stripes:layout-component> </stripes:layout-render>
post?jsonSearchData=1&firstResult="+result+"&maxResults=10
<portofino:buttons list="crud-search" cssClass="portletButton" />
Buttons are defined with the annotation @Button in any method that returns a Resolution.
If you want you can remove buttons, such as those which export to Excel and PDF. Let's override button methods in AbstractCrudAction without putting the annotation @Button.
... //Buttons disabled @Override Resolution exportReadExcel() { return super.exportReadExcel() } @Override Resolution exportReadPdf() { return super.exportReadPdf() } @Override Resolution exportSearchExcel() { return super.exportSearchExcel() } @Override Resolution exportSearchPdf() { return super.exportSearchPdf() } @Override Resolution bulkDelete() { return super.bulkDelete() } @Override Resolution bulkEdit() { return super.bulkEdit() ...
The result is the following
Step 2. Html editor in posts
Step 3. Change the post display
@Override Resolution read() { super.read(); return forwardToPortletPage("/apps/default/web/readPost.jsp"); }
Then write the jsp page readPost.jsp
<%@ page import="java.util.HashMap" %> <%@ page import="com.manydesigns.elements.xml.XhtmlBuffer" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes-dynattr.tld"%> <%@taglib prefix="mde" uri="/manydesigns-elements"%> <%@ taglib tagdir="/WEB-INF/tags" prefix="portofino" %> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <stripes:layout-render name="/skins/${skin}/portlet.jsp"> <jsp:useBean id="actionBean" scope="request" type="com.manydesigns.portofino.pageactions.crud.CrudAction"/> <stripes:layout-component name="portletTitle"> <% HashMap obj = (HashMap)actionBean.object;%> <%= obj.get("title")%> </stripes:layout-component> <stripes:layout-component name="portletBody"> <!-- Print the post --> <% HashMap obj = (HashMap)actionBean.object; XhtmlBuffer buffer = new XhtmlBuffer(); buffer.openElement("em"); buffer.write((String) obj.get("summary")); buffer.closeElement("em"); buffer.writeBr(); buffer.writeBr(); buffer.writeNoHtmlEscape((String) obj.get("body")); buffer.writeBr(); buffer.openElement("strong"); buffer.write((String) obj.get("author")); buffer.closeElement("strong"); buffer.writeBr(); out.println(buffer.toString()); %> <c:if test="${not empty actionBean.searchString}"> <input type="hidden" name="searchString" value="<c:out value="${actionBean.searchString}"/>"/> </c:if> </stripes:layout-component> <stripes:layout-component name="portletFooter"> <div class="crudReadButtons"> <portofino:buttons list="crud-read" cssClass="portletButton" /> </div> <stripes:submit name="print" value="Print" disabled="true" class="portletButton"/>--> <script type="text/javascript"> $(".crudReadButtons button[name=delete]").click(function() { return confirm ('<fmt:message key="commons.confirm" />'); }); </script> </stripes:layout-component> </stripes:layout-render>
In the next tutorial we are going to customize the "comment" page putting the list and the creation of comments in a single page.