JSP трюки, чтобы сделать шаблон проще?



на работе мне было поручено превратить кучу HTML файлы в простой . Это действительно все статично, никакой серверной логики для программирования. Я должен упомянуть, что я совершенно новичок в Java. Файлы JSP, похоже, облегчают работу с общими включениями и переменными, такими как PHP, но я хотел бы знать простой способ получить что-то вроде шаблона наследства (Django стиль) или, по крайней мере, иметь базу.jsp-файл, содержащий верхний и Нижний колонтитулы, поэтому я могу вставить содержание позже.



Бен Лингс кажется, дает некоторую надежду на его ответ здесь:
Наследование шаблонов JSP
Может кто-нибудь объяснить, как этого добиться?



учитывая, что у меня не так много времени, я думаю, что динамическая маршрутизация-это немного, поэтому я рад просто иметь URL-адреса прямо на .jsp файлы, но я открыт для предложений.



спасибо.



edit: я не хочу использовать любые внешние библиотеки, потому что это увеличило бы кривую обучения для меня и других, кто работает над проектом, и компания, в которой я работаю, была заключена контракт на это.



другой редактировать: я не уверен, если JSP tags будет полезно, потому что мой контент на самом деле не имеет никаких переменных шаблона. Что мне нужно, так это способ сделать это:



base.html:



<html><body>
{ content.body }
</body></html>


somepage.html



<wrapper:base.html>
<h1>Welcome</h1>
</wrapper>


С выход:



<html><body>
<h1>Welcome</h1>
</body></html>


I думаю, это даст мне достаточно универсальности, чтобы сделать все, что мне нужно. Это может быть достигнуто с includes но тогда мне понадобится верхняя и нижняя часть для каждой обертки, что довольно грязно.

806   4  

4 ответов:

как skaffman предложил,файлы тегов JSP 2.0 это колени пчелы.

возьмем простой пример.

поместите следующее в WEB-INF/tags/wrapper.tag

<%@tag description="Simple Wrapper Tag" pageEncoding="UTF-8"%>
<html><body>
  <jsp:doBody/>
</body></html>

теперь в вашей example.jsp страницы:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:wrapper>
    <h1>Welcome</h1>
</t:wrapper>

что делает именно то, что вы думаете.


Итак, давайте расширим это до чего-то более общего. WEB-INF/tags/genericpage.tag

<%@tag description="Overall Page template" pageEncoding="UTF-8"%>
<%@attribute name="header" fragment="true" %>
<%@attribute name="footer" fragment="true" %>
<html>
  <body>
    <div id="pageheader">
      <jsp:invoke fragment="header"/>
    </div>
    <div id="body">
      <jsp:doBody/>
    </div>
    <div id="pagefooter">
      <jsp:invoke fragment="footer"/>
    </div>
  </body>
</html>

использовать это:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:genericpage>
    <jsp:attribute name="header">
      <h1>Welcome</h1>
    </jsp:attribute>
    <jsp:attribute name="footer">
      <p id="copyright">Copyright 1927, Future Bits When There Be Bits Inc.</p>
    </jsp:attribute>
    <jsp:body>
        <p>Hi I'm the heart of the message</p>
    </jsp:body>
</t:genericpage>

что это тебе дает? Действительно много, но это становится еще лучше...


WEB-INF/tags/userpage.tag

<%@tag description="User Page template" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<%@attribute name="userName" required="true"%>

<t:genericpage>
    <jsp:attribute name="header">
      <h1>Welcome ${userName}</h1>
    </jsp:attribute>
    <jsp:attribute name="footer">
      <p id="copyright">Copyright 1927, Future Bits When There Be Bits Inc.</p>
    </jsp:attribute>
    <jsp:body>
        <jsp:doBody/>
    </jsp:body>
</t:genericpage>

чтобы использовать это: (предположим, у нас есть переменная пользователя в запросе)

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:userpage userName="${user.fullName}">
  <p>
    First Name: ${user.firstName} <br/>
    Last Name: ${user.lastName} <br/>
    Phone: ${user.phone}<br/>
  </p>
</t:userpage>

но оказывается, вам нравится использовать этот блок сведений о пользователе в других местах. Итак, мы рефакторинг. WEB-INF/tags/userdetail.tag

<%@tag description="User Page template" pageEncoding="UTF-8"%>
<%@tag import="com.example.User" %>
<%@attribute name="user" required="true" type="com.example.User"%>

First Name: ${user.firstName} <br/>
Last Name: ${user.lastName} <br/>
Phone: ${user.phone}<br/>

теперь предыдущий пример выглядит так:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:userpage userName="${user.fullName}">
  <p>
    <t:userdetail user="${user}"/>
  </p>
</t:userpage>

красота тега JSP файлы - это то, что он позволяет вам в основном помечать общую разметку, а затем рефакторинговать ее в свое удовольствие.

JSP Tag Files в значительной степени узурпировали такие вещи, как Tiles etc. по крайней мере для меня. Я нахожу их гораздо проще в использовании, поскольку единственная структура - это то, что вы ей даете, ничего предвзятого. Кроме того, вы можете использовать файлы тегов JSP для других вещей (например, фрагмент сведений о пользователе выше).

вот пример, который похож на DisplayTag, что я сделал, но это все сделано с биркой Файлы (и Stripes рамки, это S: теги..). Это приводит к таблице строк, чередующихся цветов, навигации по страницам и т. д.:

<t:table items="${actionBean.customerList}" var="obj" css_class="display">
  <t:col css_class="checkboxcol">
    <s:checkbox name="customerIds" value="${obj.customerId}"
                onclick="handleCheckboxRangeSelection(this, event);"/>
  </t:col>
  <t:col name="customerId" title="ID"/>
  <t:col name="firstName" title="First Name"/>
  <t:col name="lastName" title="Last Name"/>
  <t:col>
    <s:link href="/Customer.action" event="preEdit">
      Edit
      <s:param name="customer.customerId" value="${obj.customerId}"/>
      <s:param name="page" value="${actionBean.page}"/>
    </s:link>
  </t:col>
</t:table>

конечно теги работают с JSTL tags (типа c:if и т. д.). Единственное, что вы не можете сделать в теле тега файла тега, это добавить код скриптлета Java, но это не так много ограничений, как вы могли бы подумать. Если мне нужен материал скриптлета, я просто помещаю логику в тег и бросаю тег. Простой.

так, файлы тегов могут быть в значительной степени тем, что вы хотите, чтобы они были. На самом базовом уровне, это просто вырезать и вставить рефакторинга. Возьмите кусок макета, вырежьте его, выполните простую параметризацию и замените его вызовом тега.

на более высоком уровне вы можете делать сложные вещи, такие как этот тег таблицы, который у меня есть здесь.

Я сделал довольно легко, Django стиль JSP шаблон наследования библиотеки тегов. https://github.com/kwon37xi/jsp-template-inheritance

Я думаю, что это сделать легко управлять макетов без обучения.

пример кода :

базы.jsp: layout

<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JSP Template Inheritance</title>
    </head>

<h1>Head</h1>
<div>
    <layout:block name="header">
        header
    </layout:block>
</div>

<h1>Contents</h1>
<div>
    <p>
    <layout:block name="contents">
        <h2>Contents will be placed under this h2</h2>
    </layout:block>
    </p>
</div>

<div class="footer">
    <hr />
    <a href="https://github.com/kwon37xi/jsp-template-inheritance">jsp template inheritance example</a>
</div>
</html>

вид.ССП : содержание

<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
<layout:extends name="base.jsp">
    <layout:put name="header" type="REPLACE">
        <h2>This is an example about layout management with JSP Template Inheritance</h2>
    </layout:put>
    <layout:put name="contents">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin porta,
        augue ut ornare sagittis, diam libero facilisis augue, quis accumsan enim velit a mauris.
    </layout:put>
</layout:extends>

на основе той же основной идеи, что и в @Will Hartungответ, вот мой волшебный один тег расширяемый шаблон двигателя. Он даже включает в себя документацию и пример :-)

WEB-INF / теги / блок.тег:

<%--
    The block tag implements a basic but useful extensible template system.

    A base template consists of a block tag without a 'template' attribute.
    The template body is specified in a standard jsp:body tag, which can
    contain EL, JSTL tags, nested block tags and other custom tags, but
    cannot contain scriptlets (scriptlets are allowed in the template file,
    but only outside of the body and attribute tags). Templates can be
    full-page templates, or smaller blocks of markup included within a page.

    The template is customizable by referencing named attributes within
    the body (via EL). Attribute values can then be set either as attributes
    of the block tag element itself (convenient for short values), or by
    using nested jsp:attribute elements (better for entire blocks of markup).

    Rendering a template block or extending it in a child template is then
    just a matter of invoking the block tag with the 'template' attribute set
    to the desired template name, and overriding template-specific attributes
    as necessary to customize it.

    Attribute values set when rendering a tag override those set in the template
    definition, which override those set in its parent template definition, etc.
    The attributes that are set in the base template are thus effectively used
    as defaults. Attributes that are not set anywhere are treated as empty.

    Internally, attributes are passed from child to parent via request-scope
    attributes, which are removed when rendering is complete.

    Here's a contrived example:

    ====== WEB-INF/tags/block.tag (the template engine tag)

    <the file you're looking at right now>

    ====== WEB-INF/templates/base.jsp (base template)

    <%@ page trimDirectiveWhitespaces="true" %>
    <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
    <t:block>
        <jsp:attribute name="title">Template Page</jsp:attribute>
        <jsp:attribute name="style">
            .footer { font-size: smaller; color: #aaa; }
            .content { margin: 2em; color: #009; }
            ${moreStyle}
        </jsp:attribute>
        <jsp:attribute name="footer">
            <div class="footer">
                Powered by the block tag
            </div>
        </jsp:attribute>
        <jsp:body>
            <html>
                <head>
                    <title>${title}</title>
                    <style>
                        ${style}
                    </style>
                </head>
                <body>
                    <h1>${title}</h1>
                    <div class="content">
                        ${content}
                    </div>
                    ${footer}
                </body>
            </html>
        </jsp:body>
    </t:block>

    ====== WEB-INF/templates/history.jsp (child template)

    <%@ page trimDirectiveWhitespaces="true" %>
    <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
    <t:block template="base" title="History Lesson">
        <jsp:attribute name="content" trim="false">
            <p>${shooter} shot first!</p>
        </jsp:attribute>
    </t:block>

    ====== history-1977.jsp (a page using child template)

    <%@ page trimDirectiveWhitespaces="true" %>
    <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
    <t:block template="history" shooter="Han" />

    ====== history-1997.jsp (a page using child template)

    <%@ page trimDirectiveWhitespaces="true" %>
    <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
    <t:block template="history" title="Revised History Lesson">
        <jsp:attribute name="moreStyle">.revised { font-style: italic; }</jsp:attribute>
        <jsp:attribute name="shooter"><span class="revised">Greedo</span></jsp:attribute>
    </t:block>

--%>

<%@ tag trimDirectiveWhitespaces="true" %>
<%@ tag import="java.util.HashSet, java.util.Map, java.util.Map.Entry" %>
<%@ tag dynamic-attributes="dynattributes" %>
<%@ attribute name="template" %>
<%
    // get template name (adding default .jsp extension if it does not contain
    // any '.', and /WEB-INF/templates/ prefix if it does not start with a '/')
    String template = (String)jspContext.getAttribute("template");
    if (template != null) {
        if (!template.contains("."))
            template += ".jsp";
        if (!template.startsWith("/"))
            template = "/WEB-INF/templates/" + template;
    }
    // copy dynamic attributes into request scope so they can be accessed from included template page
    // (child is processed before parent template, so only set previously undefined attributes)
    Map<String, String> dynattributes = (Map<String, String>)jspContext.getAttribute("dynattributes");
    HashSet<String> addedAttributes = new HashSet<String>();
    for (Map.Entry<String, String> e : dynattributes.entrySet()) {
        if (jspContext.getAttribute(e.getKey(), PageContext.REQUEST_SCOPE) == null) {
            jspContext.setAttribute(e.getKey(), e.getValue(), PageContext.REQUEST_SCOPE);
            addedAttributes.add(e.getKey());
        }
    }
%>

<% if (template == null) { // this is the base template itself, so render it %>
    <jsp:doBody/>
<% } else { // this is a page using the template, so include the template instead %>
    <jsp:include page="<%= template %>" />
<% } %>

<%
    // clean up the added attributes to prevent side effect outside the current tag
    for (String key : addedAttributes) {
        jspContext.removeAttribute(key, PageContext.REQUEST_SCOPE);
    }
%>

использовать плитки. Это спасло мне жизнь.

но если вы не можете, есть включить тег, что делает его похожим на php.

тег body может на самом деле не делать то, что вам нужно, если у вас нет супер простого контента. Тег body используется для определения тела указанного элемента. Взгляните на :

<jsp:element name="${content.headerName}"   
   xmlns:jsp="http://java.sun.com/JSP/Page">    
   <jsp:attribute name="lang">${content.lang}</jsp:attribute>   
   <jsp:body>${content.body}</jsp:body> 
</jsp:element>

вы указываете имя элемента, любые атрибуты, которые может иметь элемент ("lang" в этом случае), и затем текст, который входит в него-тело. Так что если

  • content.headerName = h1,
  • content.lang = fr и
  • content.body = Heading in French

тогда выход будет

<h1 lang="fr">Heading in French</h1>

Comments

    Ничего не найдено.