Manage JavaScript and CSS with Apache Tiles
Asked Answered
C

1

10

I'm looking for a good way to manage CSS and JS resources using Apache Tiles in a similar way to ASP.NET MVC 4.

In ASP.NET MVC4 you have ContentBundles and ScriptBundles and you can simply write

@Scripts.Render("~/bundles/jquery");

It will insert your css/scripts with all the proper syntax. Then to make it even better there is @RenderSection("JavaScript", required:false) which allows you to insert JavaScript in the correct include order with it being defined on a view as so.

@section JavaScript
{
    <script type="text/javascript" src="@Url.Content("/Scripts/jquery.tablesorter.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("/Scripts/Custom/Roster.js")"></script>
}

To make this short I basically want to do something like this in Spring MVC using Apache Tiles. Is it even possible?

My initial thought and attempt was to create a "bundle" as a definition in the tiles config file but then there needs to be some JSP code to insert and create the html syntax properly. Has anyone ever attempted this before or found a good solution?

I found this example at http://www.coderanch.com/how-to/java/TilesJavaScript but it doesn't seem to be syntactically correct for Tiles 3.

master-layout.jsp

">

Here's how you'd do it for multiple js files:

tiles-defs.xml


    <!-- Child page Definition --> 
    <definition name="child.page" extends="master.page">    
        <put name="title" value="Child Page" /> 
        <put name="jsfile" value="app.childpage.jsfiles.tile" />
    </definition>

    <!-- JS Files Definition tile -->

    <definition name="app.childpage.jsfiles.tile" path="/layouts/jslayout.jsp">
        <putList name="jsfilesList">
            <add value="/config/childpage_jsfile1.js"/>
            <add value="/config/childpage_jsfile2.js"/>
            <add value="/config/childpage_jsfile3.js"/>
        </putList>
    </definition>

jslayout.jsp

<tiles:useAttribute id="list" name="jsfilesList" classname="java.util.List" />
<c:forEach var="jsfileName" items="${list}">
    <script src="<%=request.getContextPath()%><c:out value='${jsfileName}' />"></script>
</c:forEach>

Essentially I want a clean way to include all my JavaScript and CSS using Apache Tiles similar to the ASP.NET MVC bundle method. This way I'm not having to hard code the links into every single JSP file that needs something additional.

Colliery answered 17/5, 2014 at 0:55 Comment(0)
C
31

For anyone who is interested this is how I ended up implementing it. I did this using Tiles 3, I'm not sure if the syntax is different in previous versions of Tiles. It seems to work pretty well.

layout.xml

<!-- templates -->
<definition name="base" template="/WEB-INF/views/templates/template.jsp">
    <put-attribute name="title" value=""></put-attribute>
    <put-attribute name="header" value="/WEB-INF/views/tiles/shared/header.jsp"></put-attribute>
    <put-attribute name="content" value=""></put-attribute>
    <put-attribute name="footer" value="/WEB-INF/views/tiles/shared/footer.jsp"></put-attribute>
    <put-list-attribute name="javascripts">
        <add-attribute value="/static/javascript/modernizr.js" />
        <add-attribute value="/static/jquery/jquery-2.1.0.min.js" />
        <add-attribute value="/static//bootstrap/js/bootstrap.min.js" />
    </put-list-attribute>
    <put-list-attribute name="stylesheets">
        <add-attribute value="/static/bootstrap/css/bootstrap.min.css" />
        <add-attribute value="/static/stylesheets/global.css" />
    </put-list-attribute>
</definition>

<!-- HomeController  -->
<definition name="home/index" extends="base">
    <put-attribute name="title" value="Home"></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/home/home.jsp"></put-attribute>
</definition>

<!-- LoginController -->
<definition name="login/login" extends="base">
    <put-attribute name="title" value="Login"></put-attribute>
    <put-attribute name="header" value=""></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/user/login.jsp"></put-attribute>
    <put-attribute name="footer" value=""></put-attribute>
    <put-list-attribute name="stylesheets" inherit="true">
        <add-attribute value="/static/stylesheets/sign-in.css" />
    </put-list-attribute>
</definition>

<!-- UserController -->
<definition name="user/list" extends="base">
    <put-attribute name="title" value="Users"></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/user/list.jsp"></put-attribute>
</definition>

<definition name="user/add" extends="base">
    <put-attribute name="title" value="User - Add"></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/user/createOrUpdate.jsp"></put-attribute>
</definition>

<definition name="user/edit" extends="base">
    <put-attribute name="title" value="User - Edit"></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/user/createOrUpdate.jsp"></put-attribute>
</definition>

<!-- ErrorController -->
<definition name="error/error" extends="base">
    <put-attribute name="title" value="Error"></put-attribute>
    <put-attribute name="content" value="/WEB-INF/views/tiles/error/error.jsp"></put-attribute>
</definition>

template.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>

<tiles:importAttribute name="javascripts"/>
<tiles:importAttribute name="stylesheets"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="XXXXXXXXXXX">
    <meta name="description" content="Something">
    <title><tiles:insertAttribute name="title"></tiles:insertAttribute></title>
    <!-- stylesheets -->
    <c:forEach var="css" items="${stylesheets}">
        <link rel="stylesheet" type="text/css" href="<c:url value="${css}"/>">
    </c:forEach>
    <!-- end stylesheets -->
</head>
<body>

    <!--[if lt IE 10]>
        <p class="alert alert-warning">
            Warning: You are using an unsupported version of Internet Explorer. We recommend using Internet Explorer
            10+. If you are a Windows XP user you'll need to download an alternative browsers such as FireFox, Chrome,
            Opera, or Safari. 
        </p>
    <![endif]-->

    <!-- header -->
    <div id="header">
        <tiles:insertAttribute name="header"></tiles:insertAttribute>
    </div>
    <!-- end header  -->

    <!-- content -->
    <div id="content">
        <tiles:insertAttribute name="content"></tiles:insertAttribute>
    </div>
    <!-- end content -->

    <!-- footer -->
    <div id="footer">
        <tiles:insertAttribute name="footer"></tiles:insertAttribute>
    </div>
    <!-- end footer -->

    <!-- scripts -->
    <c:forEach var="script" items="${javascripts}">
        <script src="<c:url value="${script}"/>"></script>
    </c:forEach>
    <!-- end scripts -->

</body>
</html>
Colliery answered 28/5, 2014 at 15:17 Comment(4)
Thank you for posting your solution! Exactly what I was looking for.Flexuous
why we define jsp dependencies in tiles configuration file ? This would be rework for developer since designer declare those dependencies in the html/jsp file .Polyglot
Thanks for your answer! It solves my issue, but I still would like to add some JS directly in the page. Does Tiles have some sort of "sections" where you could define content that would be included in the main layout directly from your JSPs?Minimus
Since the javascripts is just a model object, try getting it from the controller and add more page specific scripts to it. The JSTL should render out the updated listFlexile

© 2022 - 2024 — McMap. All rights reserved.