Using Layouts in Velocity with Spring - bahkified/Notes GitHub Wiki

#App Using a regular Spring MVC based web application, there is a controller that returns the template called accountOverview. The view content will be held in a Velocity variable: $screen_content.

Dependencies

Besides the regular Spring dependencies, you need to include the Velocity dependencies:

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>

Configure Spring MVC: app-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="net.laureate.billing.controller"/>

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityLayoutView" />
        <property name="layoutUrl" value="layout.vm"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".vm"/>
        <property name="exposeSpringMacroHelpers" value="true"/>
    </bean>

    <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/templates/"/>
    </bean>
</beans>

layout.vm

#parse("head.vm")
<body>

<div>
    <div>
        #parse("nav-header.vm")
    </div>
    <div class="container-fluid" style="padding-top: 80px;">
        $screen_content
    </div>
</div>
#include("footer.vm")
</body>

head.vm

<!DOCTYPE html>
<head>
    <title>Example Page</title>
    <base href="/uofl-billing/"/>

    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="css/app.css">

    <script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>

nav-header.vm

<div class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container-fluid">
        <div class="navbar-header">
            <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-collapse1">
                <span class="sr-only">Toggle Navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a href="app/accountOverview" class="navbar-brand visible-xs">Brand</a>
        </div>
        <div class="collapse navbar-collapse" id="navbar-collapse1">
            <ul class="nav navbar-nav col-xs-12 navTab">
                <li class="col-sm-3" id="overviewTab">
                    <a class="col-xs-12" href="app/accountOverview">
                        <i class="fa fa-leaf icon col-xs-1 col-sm-3"></i>
                        <div class="col-xs-9">Account Overview</div>
                    </a>
                </li>
                <li class="col-sm-3" id="billingHistoryTab">
                    <a class="col-xs-12" href="app/billingHistory">
                        <i class="fa fa-file-text icon col-xs-1 col-sm-3"></i>
                        <div class="col-xs-9">Billing History</div>
                    </a>
                </li>
                <li class="col-sm-3" id="paymentHistoryTab">
                    <a class="col-xs-12" href="app/paymentHistory">
                        <i class="fa fa-retweet icon col-xs-1 col-sm-3"></i>
                        <div class="col-xs-9">Payment History</div>
                    </a>
                </li>
                <li class="col-sm-3" id="paymentCenterTab">
                    <a class="col-xs-12" href="app/paymentCenter">
                        <i class="fa fa-credit-card icon col-xs-1 col-sm-3"></i>
                        <div class="col-xs-9">Payment Center</div>
                    </a>
                </li>
            </ul>
        </div>
    </div>
</div>

footer.vm

<script src="js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/floatthead/1.2.7/jquery.floatThead.min.js"></script>
<script src="js/app.js"></script>

accountOverview.vm

#parse("summaryPanel.vm")
<div class="col-xs-12 col-sm-8" id="contentContainer">
    <div id="alertsPanel" class="col-xs-12" style="border-bottom:2px solid #757575;padding-bottom:30px;">
        <h2>Alerts</h2>
        <div class="col-xs-12 bg-warning" style="padding-top:12px;" data-dismiss="alert">
            <i class="col-xs-1 fa fa-warning pull-left"></i>
            <p class="col-xs-10" style="border-right:1px solid #dedede">
                A Payment of $current_balance is due before registering for the next module. The last day to
                register is $due_date.
            </p>
            <span class="fa fa-times pull-right" id="closeBtn" style="cursor:pointer;" data-target="#alertsPanel"></span>
        </div>
    </div>
    <div id="infoPanel" class="col-xs-12 col-sm-8">
        <h2>Billing Information</h2>
        <a href="http://example.com/student-agreement">View your student agreement.</a>
        <div id="pointsPanel" class="col-xs-12 content">
            #if ($overview)
                #foreach( $category in $overview )
                    <h4 class="col-xs-12">
                        $category.label: &emsp;
                        <span class="lead">$category.total</span>
                        #if ( $!category.description != "" )
                            <i class="fa fa-exclamation-circle" id="descriptionToggle" data-container="body"
                               data-toggle="popover" data-placement="right" data-content="$category.description"></i>
                        #end
                    </h4>
                #end
            #end
        </div>
    </div>
</div>
<script>
    $(document).ready(function() {
        $("#overviewTab").addClass("selected");
        $("#descriptionToggle").popover();
    });
</script>

Resources

⚠️ **GitHub.com Fallback** ⚠️