Ejemplo completo de extensión frontend
Este ejemplo muestra cómo extender rápidamente las funciones de OpenKM con tecnologías JSP, HTML, CSS y JavaScript utilizando la API Java de OpenKM, y cómo utilizar las funciones JavaScript de los métodos JAVA de frontend expuestos.
Descargue el código del ejemplo de extensión complete_extension_sample.zip.
Descripción
Sección titulada «Descripción»El ejemplo se muestra en una nueva pestaña de Workspace.
La pantalla principal se muestra como una barra de herramientas con tres botones:
- El primer botón lleva a la pantalla principal del ejemplo.
- El segundo botón muestra el ejemplo 1
- El segundo botón muestra el ejemplo 2.
Estructura del proyecto:

Instalación
Sección titulada «Instalación»- Detenga la aplicación.
- Abra el contenido del archivo descargado en la carpeta $TOMCAT_HOME/webapps/OpenKM ( o mejor, en OpenKM.war )
- Elimine $TOMCAT_HOME/work/Catalina/localhost
- Inicie la aplicación.
- Compruebe la url http://localhost:8080/OpenKM/sample.
Detalles de implementación
Sección titulada «Detalles de implementación»index.jsp
Sección titulada «index.jsp»Index.jsp controla la altura del iframe con código JavaScript.
Otro aspecto importante es que, por ejemplo tras subir un documento ( Sample 2 ), se utiliza el parámetro urlToOpen para indicar qué url debe abrirse.
String urlToOpen = URLDecoder.decode(WebUtils.getString(request, "urlToOpen"),"UTF-8");if (urlToOpen.equals("")) { urlToOpen = "home.jsp";}menu.jsp
Sección titulada «menu.jsp»Contiene las definiciones de las urls del menú.

home.jsp
Sección titulada «home.jsp»Establece la pantalla principal de inicio.

Ejemplo 1
Sección titulada «Ejemplo 1»Se compone de 4 archivos:
- action.jsp ( el controlador principal donde se establece la lógica ).
- distributor.jsp ( la capa principal con dos columnas al 50% ).
- full_list.jsp ( muestra la lista completa sin control especial de JavaScript ).
- filtered_list.jsp ( muestra una lista filtrada sin control especial de JavaScript ).
action.jsp
Sección titulada «action.jsp»El controlador principal.
<%@page import="java.util.Map"%><%@page import="java.util.HashMap"%><%@page import="java.util.List"%><%@page import="java.util.ArrayList"%><%@ page import="java.text.SimpleDateFormat" %><%@ page import="java.io.IOException" %><%@ page import="org.slf4j.Logger" %><%@ page import="org.slf4j.LoggerFactory" %><%@ page import="com.openkm.bean.Document" %><%@ page import="com.openkm.util.WebUtils" %><%@ page import="com.openkm.api.OKMDocument" %><%@ page extends="com.openkm.extension.servlet.BaseServlet" %><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%!private static Logger log = LoggerFactory.getLogger("com.openkm.sample");public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String action = WebUtils.getString(request, "action"); try { list(request, response); } catch (Exception e) { log.error(e.getMessage(), e); sendErrorRedirect(request, response, e); }}
// Used by fileupload return and filterpublic void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException { String action = WebUtils.getString(request, "action"); try { list(request, response); } catch (Exception e) { log.error(e.getMessage(), e); sendErrorRedirect(request, response, e); }}
private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, Exception { SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); String docPath = (String) request.getAttribute("docPath"); String nameFilter = WebUtils.getString(request,"nameFilter");
// Pending docs List<Map<String,String>> pendingDocMaps = new ArrayList<Map<String,String>>(); for ( Document doc : OKMDocument.getInstance().getChildren(null, "/okm:root")) { Map<String,String> docMap = new HashMap<String,String>(); docMap.put("name",doc.getPath().substring(doc.getPath().lastIndexOf("/")+1)); docMap.put("uuid",doc.getUuid()); docMap.put("path",doc.getPath()); docMap.put("mimeType",doc.getMimeType()); docMap.put("lastModified", df.format(doc.getLastModified().getTime())); pendingDocMaps.add(docMap); }
ServletContext sc = getServletContext(); sc.setAttribute("docPath",docPath); sc.setAttribute("nameFilter",nameFilter); sc.setAttribute("pendingDocuments",pendingDocMaps); sc.getRequestDispatcher("/sample/sample2/distributor.jsp").forward(request, response);}%>distributor.jsp
Sección titulada «distributor.jsp»La capa principal.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/sample/css/style.css" /> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.7.1.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath() %>/js/vanadium-min.js" ></script></head><body> <table width="100%"> <tbody> <tr> <td valign="top" width="50%"> <jsp:include page="/sample/sample1/full_list.jsp"></jsp:include> </td> <td valign="top" width="10"></td> <td valign="top" width="50%"> <jsp:include page="/sample/sample1/filtered_list.jsp"></jsp:include> </td> </tr> </tbody> </table></body></html>full_list.jsp
Sección titulada «full_list.jsp»Muestra la lista de documentos.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %><script type="text/javascript"> // Note the parent.parent call because iframe is into other iframe function go(uuid) { alert('Document UUID:'+uuid); parent.parent.jsOpenPathByUuid(uuid); }</script><h1>Full list of /okm:root documents</h1><table class="results" style="white-space: nowrap;" cellpadding="3" width="100%"> <thead> <tr> <th></th><th>Author</th><th>Document</th><th>Date</th><th></th> </tr> </thead> <tbody> <c:forEach var="document" items="${leftDocsMaps}" varStatus="row"> <tr> <td valign="center"><img src="<%=request.getContextPath() %>/mime/${document.mimeType}"/></td> <td>${document.author}</td> <td>${document.name}</td> <td>${document.lastModified}</td> <td align="center"> <a href="javascript:go('${document.uuid}')"><img src="<%=request.getContextPath() %>/sample/img/action/goto_document.gif" alt="Show document" title="Show document"/></a> </td> </tr> </c:forEach> </tbody></table>Captura de pantalla de la vista del ejemplo 1
Sección titulada «Captura de pantalla de la vista del ejemplo 1»
Ejemplo 2
Sección titulada «Ejemplo 2»Se compone de 4 archivos:
- action.jsp ( el controlador principal donde se establece la lógica ).
- add_form.jsp ( formulario para subir un nuevo documento )
- distributor.jsp ( la capa principal con dos columnas al 50% con JavaScript ).
- full_list.jsp ( muestra la lista completa con control especial de JavaScript para la altura de la tabla).
- pending.jsp ( contenido estático ).
action.jsp
Sección titulada «action.jsp»El controlador principal.
<%@page import="java.util.Map"%><%@page import="java.util.HashMap"%><%@page import="java.util.List"%><%@page import="java.util.ArrayList"%><%@ page import="java.text.SimpleDateFormat" %><%@ page import="java.io.IOException" %><%@ page import="org.slf4j.Logger" %><%@ page import="org.slf4j.LoggerFactory" %><%@ page import="com.openkm.bean.Document" %><%@ page import="com.openkm.util.WebUtils" %><%@ page import="com.openkm.api.OKMDocument" %><%@ page extends="com.openkm.extension.servlet.BaseServlet" %><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%!
private static Logger log = LoggerFactory.getLogger("com.openkm.sample");public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String action = WebUtils.getString(request, "action"); try { list(request, response); } catch (Exception e) { log.error(e.getMessage(), e); sendErrorRedirect(request, response, e); }}
// Used by fileupload return and filterpublic void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException { String action = WebUtils.getString(request, "action"); try { list(request, response); } catch (Exception e) { log.error(e.getMessage(), e); sendErrorRedirect(request, response, e); }}
private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, Exception { SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); String docPath = (String) request.getAttribute("docPath"); String nameFilter = WebUtils.getString(request,"nameFilter"); // Pending docs List<Map<String,String>> pendingDocMaps = new ArrayList<Map<String,String>>(); for ( Document doc : OKMDocument.getInstance().getChildren(null, "/okm:root")) { Map<String,String> docMap = new HashMap<String,String>(); docMap.put("name",doc.getPath().substring(doc.getPath().lastIndexOf("/")+1)); docMap.put("uuid",doc.getUuid()); docMap.put("path",doc.getPath()); docMap.put("mimeType",doc.getMimeType()); docMap.put("lastModified", df.format(doc.getLastModified().getTime())); pendingDocMaps.add(docMap); } ServletContext sc = getServletContext(); sc.setAttribute("docPath",docPath); sc.setAttribute("nameFilter",nameFilter); sc.setAttribute("pendingDocuments",pendingDocMaps); sc.getRequestDispatcher("/sample/sample2/distributor.jsp").forward(request, response);}%>distributor.jsp
Sección titulada «distributor.jsp»La capa principal.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/sample/css/style.css" /> <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/css/jquery.tablescroll.css"/> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.7.1.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath() %>/js/vanadium-min.js" ></script> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery.tablescroll.js"></script></head><body> <div id="leftPanel" style="float: left;"> <jsp:include page="/sample/sample2/add_form.jsp"></jsp:include> <jsp:include page="/sample/sample2/full_list.jsp"></jsp:include> </div> <div id="centerPanel" style="float: left; width: 12px;"> <div id="verticalSeparator" class="verticalSeparator"></div> </div> <div id="rightPanel" style="float: left;"> <jsp:include page="/sample/sample2/pending.jsp"></jsp:include> </div>
<script type="text/javascript"> var width = $(window).width()-12; // Deleting middle panel var height = $(window).height();
// Setting height $('#verticalSeparator').height(height); $('#leftPanel').height(height); $('#rightPanel').height(height); // Setting width $('#leftPanel').width(parseInt(width/2)); $('#centerPanel').width(12); $('#rightPanel').width((width-parseInt((width/2)))); </script></body></html>add_form.jsp
Sección titulada «add_form.jsp»Formulario para subir un nuevo documento.
<%@ page import="com.openkm.frontend.client.constants.ui.UIFileUploadConstants" %><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><h2 id="headerTitle_new_register">Upload new file</h2><form enctype="multipart/form-data" method="post" action="<%=request.getContextPath() %>/frontend/FileUpload"> <input type="hidden" name="path" value="/okm:root"> <input type="hidden" name="action" value="<%=UIFileUploadConstants.ACTION_INSERT%>"> <input type="hidden" name="message" value=""> <input type="hidden" name="comment" value=""> <input type="hidden" name="redirect" value="/sample/sample2/action.jsp"> <table class="form"> <tbody> <c:if test="${docPath != null && docPath != ''}"> <tr> <td><div class="ok">Document sended</div></td> </tr> </c:if> <tr> <td> <div id="file_error" style="display:none; color : red;">File is mandatory.</div> <input type="file" name="file" class=":required;;file_error :only_on_blur"> </td> </tr> <tr> <td align="center"><input type="submit" value="Send"></td> </tr> </tbody> </table></form>full_list.jsp
Sección titulada «full_list.jsp»Muestra una lista de documentos.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %><script type="text/javascript"> // Note the parent.parent call because iframe is into other iframe function go(uuid) { alert('Document UUID:'+uuid); parent.parent.jsOpenPathByUuid(uuid); }</script><h2 class="top">Full document list from /okm:root</h2><div align="center" style="padding: 0px 20px 0px 5px"> <div class="tablescroll"> <table id="docsPendingTable" width="100%" cellspacing="0" style="white-space: nowrap;"> <thead> <tr> <td>Id</td><td>Document</td><td>Date</td><td></td> </tr> </thead> <tbody> <c:set var="first" value="true"></c:set> <c:forEach var="document" items="${pendingDocuments}" varStatus="row"> <c:choose> <c:when test="${first==true}"> <tr class="first"> </c:when> <c:otherwise> <tr> </c:otherwise> </c:choose> <td valign="center"><img src="<%=request.getContextPath() %>/mime/${document.mimeType}"/></td> <td>${document.name}</td> <td>${document.lastModified}</td> <td align="center"><a href="javascript:go('${document.uuid}')"><img src="<%=request.getContextPath() %>/sample/img/action/goto_document.gif" alt="Show document" title="Show document"/></a></td> </tr> <c:set var="first" value="false"></c:set> </c:forEach> </tbody> </table> </div></div>
<script type="text/javascript">//Calculating table height removing from total other elements heightvar pendingTableHeight = $(window).height() - (parseInt($('#docsPendingTable').offset().top) + 35);/*<![CDATA[*/jQuery(document).ready(function($){ $('#docsPendingTable').tableScroll({height:pendingTableHeight});});/*]]>*/</script>Captura de pantalla de la vista del ejemplo 2
Sección titulada «Captura de pantalla de la vista del ejemplo 2»