Commit 0f1257e2 authored by Matija Obreza's avatar Matija Obreza

baseUrl and cdnServers exposed as request attributes

- "props" bean removed from request context (props.baseUrl replaced with just baseUrl)
- cdnServers.next returns a random server from "cdn.servers" list
- host.name and base.url are required; cdnServers defaults to ${base.url}
- .properties files updated
parent 27540bcf
......@@ -135,7 +135,7 @@ module.exports = function(grunt) {
'bower_components/tinymce/tinymce.jquery.js', 'bower_components/tinymce/themes/modern/theme.js', 'bower_components/tinymce/plugins/link/plugin.js',
'bower_components/tinymce/plugins/autolink/plugin.js', 'bower_components/tinymce/plugins/code/plugin.js', 'bower_components/leaflet/dist/leaflet.js',
'bower_components/leaflet-locationfilter/src/locationfilter.js', 'bower_components/bootstrap-sass/assets/javascripts/bootstrap.js', 'bower_components/jquery-ui/jquery-ui.js',
'bower_components/jquery-ui/ui/autocomplete.js', 'bower_components/dyn-css/lib/dyncss.js', 'bower_components/jstree/dist/jstree.min.js' ],
'bower_components/jquery-ui/ui/autocomplete.js', 'bower_components/jstree/dist/jstree.min.js' ],
dest : '<%= app.dist1 %>/js/libraries.js',
},
app1 : {
......
......@@ -13,7 +13,6 @@
"jquery.tinymce": "*",
"bootstrap-sass": "~3.3.6",
"jquery-ui": "~1.11.4",
"dyn-css": "~0.8.1",
"webfont-notosans": "~0.1.0",
"fontawesome": "~4.4.0",
"highcharts": "~4.1.8",
......
......@@ -6,8 +6,8 @@ services:
environment:
- spring.profiles.active=dev
- JAVA_OPTIONS=-Xms1800M -Xmx1800M -server -Dnetworkaddress.cache.ttl=10
- base.host=${CI_ENVIRONMENT_SLUG}.review.genesys-pgr.org
- base.hostname=${CI_ENVIRONMENT_SLUG}.review.genesys-pgr.org
- host.name=${CI_ENVIRONMENT_SLUG}.review.genesys-pgr.org
- base.url=https://${CI_ENVIRONMENT_SLUG}.review.genesys-pgr.org
- robots.allow=false
- db.url=jdbc:hsqldb:mem:genesys;sql.syntax_mys=true
- db.driverClassName=org.hsqldb.jdbc.JDBCDriver
......
......@@ -55,9 +55,7 @@ cookies between all .genesys-pgr.org domains.
plan to run on HTTPS protocol.
|base.cookie-http-only|false|AJAX calls from the browser sometimes require session information for
user authentication. Keep this value `false`.
|cdn.server|${base.url}|Default configuration does not use a CDN and defaults to the `base.url`.
|cdn.base|${cdn.server}|
|cdn.flags.url|${cdn.base}/html/0/images/flags|
|cdn.servers|${base.url}|Default configuration does not use a CDN and defaults to the `base.url`.
|robots.allow|false|Setting this to `true` will produce a `/robots.txt` response that allows robots to index
the site.
|===
......@@ -225,11 +223,6 @@ Genesys uses a number of external service APIs to provide users with advanced fu
theme.defaultThemeName=dev
# TileServer CDN
#tileserver.cdn='https://s1'
#tileserver.cdn='https://s1.cdn.genesys-pgr.org','https://s2.cdn.genesys-pgr.org','https://s3.cdn.genesys-pgr.org','https://s4.cdn.genesys-pgr.org'
tileserver.cdn='${base.url}'
# TileServer Cache
cache.defaultCacheSize=5000
cache.tileserver.max-size=1000
......
/*
* Copyright 2016 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* This class provides application properties on JSP pages
*/
@Component("props")
public class ApplicationProps implements InitializingBean {
@Value("${tileserver.cdn}")
private String tileserverCdn;
@Value("${cdn.server}")
private String cdnServer;
@Value("${base.url}")
private String baseUrl;
public String getTileserverCdn() {
return tileserverCdn;
}
@Override
public void afterPropertiesSet() throws Exception {
}
public String getCdnServer() {
return this.cdnServer;
}
public String getBaseUrl() {
return baseUrl;
}
}
/**
* Copyright 2014 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.servlet.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component("envVarFilter")
public class EnvVariablesFilter extends OncePerRequestFilter {
@Value("${google.analytics.account}")
private String googleAnalyticsAccount;
@Value("${cdn.flags.url}")
private String cdnFlagsUrl;
@Value("${base.url}")
private String baseUrl;
@Override
public void afterPropertiesSet() throws ServletException {
super.afterPropertiesSet();
cdnFlagsUrl = StringUtils.defaultIfBlank(cdnFlagsUrl, null);
googleAnalyticsAccount = StringUtils.defaultIfBlank(googleAnalyticsAccount, null);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (googleAnalyticsAccount != null) {
request.setAttribute("googleAnalyticsAccount", googleAnalyticsAccount);
}
if (cdnFlagsUrl != null) {
request.setAttribute("cdnFlagsUrl", cdnFlagsUrl);
}
if (baseUrl != null) {
request.setAttribute("baseUrl", baseUrl);
}
filterChain.doFilter(request, response);
}
}
......@@ -19,14 +19,18 @@ package org.genesys2.spring;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.BeanCreationException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class AddStuffInterceptor implements HandlerInterceptor {
public class AddStuffInterceptor implements HandlerInterceptor, InitializingBean {
// @Autowired
// private RequestTracker requestTracker;
......@@ -37,31 +41,75 @@ public class AddStuffInterceptor implements HandlerInterceptor {
@Value("${build.revision}")
private String buildRevision;
@Value("${cdn.servers}")
private String[] cdnServers;
@Value("${base.url}")
private String baseUrl;
@Value("${google.analytics.account}")
private String googleAnalyticsAccount;
public abstract interface RandomString {
/// Get a random CDN server
public String getNext();
/// Return all CDN servers in a JS array
public String getServerList();
}
private RandomString randomCdnServer;
@Override
public void afterPropertiesSet() throws Exception {
googleAnalyticsAccount = StringUtils.defaultIfBlank(googleAnalyticsAccount, null);
final String allCdnJs = new ObjectMapper().writeValueAsString(cdnServers);
randomCdnServer = new RandomString() {
@Override
public String getNext() {
return cdnServers[RandomUtils.nextInt(cdnServers.length)];
}
@Override
public String getServerList() {
return allCdnJs;
}
};
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView modelAndView) throws Exception {
final long startTime = (Long) arg0.getAttribute("springStartTime");
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView modelAndView) throws Exception {
final long startTime = (Long) request.getAttribute("springStartTime");
final long endTime = System.currentTimeMillis();
final long executeTime = endTime - startTime;
arg0.setAttribute("springExecuteTime", executeTime);
request.setAttribute("springExecuteTime", executeTime);
try {
// arg0.setAttribute("lastGet", requestTracker.getLastGet());
} catch (BeanCreationException e) {
// No requestTracker bean
}
// try {
// // arg0.setAttribute("lastGet", requestTracker.getLastGet());
// } catch (BeanCreationException e) {
// // No requestTracker bean
// }
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
final long startTime = System.currentTimeMillis();
arg0.setAttribute("springStartTime", startTime);
arg0.setAttribute("buildName", buildName);
arg0.setAttribute("buildRevision", buildRevision);
request.setAttribute("springStartTime", startTime);
request.setAttribute("buildName", buildName);
request.setAttribute("buildRevision", buildRevision);
request.setAttribute("cdnServers", randomCdnServer);
request.setAttribute("baseUrl", baseUrl);
if (googleAnalyticsAccount != null) {
request.setAttribute("googleAnalyticsAccount", googleAnalyticsAccount);
}
return true;
}
......
......@@ -83,6 +83,9 @@ public class WebConfiguration extends WebMvcConfigurerAdapter {
@Resource
private Set<String> supportedLocales;
@Value("${base.url}")
private String baseUrl;
@Scope("singleton")
@Bean
@Override
......@@ -133,7 +136,7 @@ public class WebConfiguration extends WebMvcConfigurerAdapter {
resolver.setPrefix("/WEB-INF/jsp");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
resolver.setExposedContextBeanNames(new String[] { "props", "jspHelper" });
resolver.setExposedContextBeanNames(new String[] { "jspHelper" });
resolver.setRedirectHttp10Compatible(false);
resolver.setRequestContextAttribute("requestContext");
resolver.setViewClass(JstlView.class);
......
......@@ -113,12 +113,6 @@ public class WebInitializer extends AbstractAnnotationConfigDispatcherServletIni
localeURLFilter.setInitParameter("allowed-locales", "en es de fr fa ar ru zh pt");
localeURLFilter.addMappingForUrlPatterns(null, false, "/*");
// EnvVar filter configuration
// Adds variables to all requests
// TODO Upgrade to @WebFilter
final FilterRegistration.Dynamic envVarFilter = servletContext.addFilter("envVarFilter", new DelegatingFilterProxy("envVarFilter"));
envVarFilter.addMappingForUrlPatterns(null, false, "/*");
// http://stackoverflow.com/a/22409634
final ConfigurableSiteMeshFilter sitemeshWithErrors = new ConfigurableSiteMeshFilter() {
@Override
......
......@@ -14,6 +14,15 @@
# limitations under the License.
#-------------------------------------------------------------------------------
# Key configuration
host.name=localhost
base.url=http://${host.name}:8080
cdn.servers=${base.url}
base.cookie-domain=${host.name}
base.cookie-secure=false
base.cookie-http-only=true
#Paginator
paginator.default.maxPageSize=500
paginator.default.pageSize=50
......@@ -31,15 +40,6 @@ build.artifactId=${project.artifactId}
build.name=${project.artifactId}-${buildNumber}
build.revision=${buildNumber}
base.host=localhost
base.hostname=${base.host}:8080
host.name=${base.hostname}
base.url=http://${base.hostname}
base.cookie-domain=${base.host}
base.cookie-secure=false
base.cookie-http-only=true
# robots.txt
robots.allow=false
......@@ -78,12 +78,6 @@ itpgrfa.easysmta.password=foo
# GA Account
google.analytics.account=
# CDN
cdn.server=${base.url}
cdn.base=${cdn.server}
cdn.flags.url=${cdn.base}/html/1/images/flags
# Content creation on startup
auto.createContent=false
......@@ -148,11 +142,6 @@ theme.defaultThemeName=dev
scheduler.tokens.cleanup.hours=1
# TileServer CDN
#tileserver.cdn='https://s1'
#tileserver.cdn='https://s1.cdn.genesys-pgr.org','https://s2.cdn.genesys-pgr.org','https://s3.cdn.genesys-pgr.org','https://s4.cdn.genesys-pgr.org'
tileserver.cdn='${base.url}'
# Cache configuration
cache.defaultCacheSize=2000
cache.eviction-policy=LRU
......
......@@ -2,17 +2,16 @@
<c:choose>
<c:when test="${requestContext.theme.name eq 'one'}">
<link href="<c:url value="/html/1/styles/all.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/all.min.css" />" type="text/css" rel="stylesheet" />
</c:when>
<c:when test="${requestContext.theme.name eq 'all'}">
<link href="<c:url value="/html/1/styles/bootstrap.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="/html/1/styles/other.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="/html/1/styles/genesys.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/bootstrap.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/other.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/genesys.css" />" type="text/css" rel="stylesheet" />
</c:when>
<c:otherwise>
<link href="<c:url value="/html/1/styles/bootstrap.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="/html/1/styles/other.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="/html/1/styles/genesys.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/bootstrap.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/other.min.css" />" type="text/css" rel="stylesheet" />
<link href="<c:url value="${cdnServers.next}/html/1/styles/genesys.css" />" type="text/css" rel="stylesheet" />
</c:otherwise>
</c:choose>
......@@ -44,7 +44,7 @@
</ul>
<div class="text-center" id="copyright">
<p>
<spring:message code="footer.copyright-statement" arguments='<%= new SimpleDateFormat("YYYY").format(new Date()) %>' htmlEscape="false" />
<spring:message code="footer.copyright-statement" arguments="2017" htmlEscape="false" />
</p>
</div>
</div>
......@@ -60,20 +60,20 @@
<%-- Placed at the end of the document so the pages load faster --%>
<c:choose>
<c:when test="${requestContext.theme.name eq 'one'}">
<script type="text/javascript" src="<c:url value="/html/1/js/all.min.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/all.min.js" />"></script>
</c:when>
<c:when test="${requestContext.theme.name eq 'all'}">
<script type="text/javascript" src="<c:url value="/html/1/js/libraries.min.js" />"></script>
<script type="text/javascript" src="<c:url value="/html/1/js/genesys.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/libraries.min.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/genesys.js" />"></script>
</c:when>
<c:otherwise>
<script type="text/javascript" src="<c:url value="/html/1/js/libraries.js" />"></script>
<script type="text/javascript" src="<c:url value="/html/1/js/genesys.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/libraries.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/genesys.js" />"></script>
</c:otherwise>
</c:choose>
<script type="text/javascript">
L.Icon.Default.imagePath = '<c:url value="/html/1/styles/images" />';
L.Icon.Default.imagePath = '<c:url value="${cdnServers.next}/html/1/styles/images" />';
<%--dynCss.config.debug=true;--%>
//enableSessionWarning(${pageContext.session.maxInactiveInterval});
</script>
......
......@@ -18,7 +18,7 @@
<meta name="_csrf_header" content="${_csrf.headerName}" />
<!-- Links -->
<link rel="shortcut icon" href="<c:url value="/html/1/images/genesys.png" />" />
<link rel="shortcut icon" href="<c:url value="${cdnServers.next}/html/1/images/genesys.png" />" />
<!-- opensearch.org -->
<link rel="search" hreflang="${pageContext.response.locale.language}" type="application/opensearchdescription+xml" href="<c:url value="/acn/opensearch/desc" />"
......
......@@ -418,9 +418,9 @@
<div class="section-inner-content clearfix">
<div class="row imagegallery thumbs" id="accession-images-thumbs">
<c:forEach items="${imageGallery.images}" var="image">
<div x-uuid="<c:out value=" ${image.uuid}" />" x-ext="<c:out value=" ${image.extension}" />" style="cursor: pointer;" class="col-lg-2 col-md-4 col-sm-4 col-xs-6">
<div x-uuid="<c:out value="${image.uuid}" />" x-ext="<c:out value="${image.extension}" />" style="cursor: pointer;" class="col-lg-2 col-md-4 col-sm-4 col-xs-6">
<div class="img-wrapper">
<img src="<c:url value=" /repository/d/_thumbs${image.thumbnailPath}/${thumbnailFormat}.png" />" alt="<c:out value=" ${image.title}" />"/>
<img src="<c:url value="${cdnServers.next}/repository/d/_thumbs${image.thumbnailPath}/${thumbnailFormat}.png" />" alt="<c:out value="${image.title}" />"/>
</div>
</div>
</c:forEach>
......@@ -1213,11 +1213,12 @@
var elem = box.find('.downloadLink').show().find('a').first().attr('href', box.parent().parent().find('.theimage').first().attr('src'));
}
function showImage(imagegalleryFrame, imageUuid, imageExt) {
var baseHref = '<c:url value="/repository/d" />/';
var baseHref = '<c:url value="/repository/d/" />';
var imageViewer = $(imagegalleryFrame).find('.theimage').first();
var metadataBox = $(imagegalleryFrame).find('.metadata').first();
imageViewer.attr('src', baseHref + imageUuid.substring(0, 3) + '/' + imageUuid + imageExt);
// console.log('Image source: ' + imageViewer.src) console.log(imageViewer.attr('src'));
imageViewer.attr('src', '<c:url value="${cdnServers.next}/repository/d/" />' + imageUuid.substring(0, 3) + '/' + imageUuid + imageExt);
// console.log('Image source: ' + imageViewer.src);
// console.log(imageViewer.attr('src'));
$(imagegalleryFrame).show();
$(metadataBox).hide();
......
......@@ -13,7 +13,7 @@
<html>
<head>
<title><spring:message code="accession.page.data.title"/></title>
<script type="text/javascript" src="<c:url value="/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="/explore/i18n.js"/>"></script>
</head>
......
......@@ -5,7 +5,7 @@
<html>
<head>
<title><spring:message code="maps.accession-map"/></title>
<script type="text/javascript" src="<c:url value="/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="/explore/i18n.js"/>"></script>
</head>
<body class="map-page overview-page explore-page">
......@@ -701,9 +701,9 @@
if ($(this).find("input:checkbox").is(":checked")) {
if (layers[title] == null) {
layers[title] = L.tileLayer("{s}/explore/tile/{z}/{x}/{y}?filter=" + filter + "&color=" + tilesColor, {
attribution: "<a href='${props.baseUrl}'>Genesys</a>",
attribution: "<a href='${baseUrl}'>Genesys</a>",
styleId: 22677,
subdomains: [${props.tileserverCdn}]
subdomains: ${cdnServers.serverList}
}).addTo(map);
}
} else {
......@@ -911,9 +911,9 @@
function loadTiles() {
layer = L.tileLayer("{s}/explore/tile/{z}/{x}/{y}?filter=" + JSON.stringify(jsonData), {
attribution: "Accession localities from <a href='${props.baseUrl}'>Genesys PGR</a>",
attribution: "Accession localities from <a href='${baseUrl}'>Genesys PGR</a>",
styleId: 22677,
subdomains: [${props.tileserverCdn}]
subdomains: ${cdnServers.serverList}
});
layer.addTo(map);
if(shouldGetBoundingBox()) {
......@@ -925,9 +925,9 @@
if (layer !== null) {
map.removeLayer(layer);
layer = L.tileLayer("{s}/explore/tile/{z}/{x}/{y}?filter=" + JSON.stringify(jsonData), {
attribution: "Accession localities from <a href='${props.baseUrl}'>Genesys PGR</a>",
attribution: "Accession localities from <a href='${baseUrl}'>Genesys PGR</a>",
styleId: 22677,
subdomains: [${props.tileserverCdn}]
subdomains: ${cdnServers.serverList}
});
layer.addTo(map);
if(shouldGetBoundingBox()) {
......
......@@ -5,7 +5,7 @@
<html>
<head>
<title><spring:message code="data-overview"/></title>
<script type="text/javascript" src="<c:url value="/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/browse.js" />"></script>
<script type="text/javascript" src="<c:url value="/explore/i18n.js"/>"></script>
</head>
<body class="overview-page explore-page">
......
......@@ -91,7 +91,7 @@
<div id="container" style="min-height: 500px; min-width: 310px; margin: 0 auto"></div>
<content tag="javascript">
<script type="text/javascript" src="<c:url value="/html/js/genesyshighcharts.min.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/genesyshighcharts.min.js" />"></script>
<script type="text/javascript">
$(function () {
'use strict';
......
......@@ -9,10 +9,10 @@
<title><spring:message code="page.home.title" /></title>
<subtitle><spring:message code="activity.recent-activity" /></subtitle>
<link href="<c:url value="${props.baseUrl}/content/news/feed.atom" />" rel="self" />
<link href="<c:url value="${props.baseUrl}" />" />
<link href="<c:url value="${baseUrl}/content/news/feed.atom" />" rel="self" />
<link href="<c:url value="${baseUrl}" />" />
<id>urn:uuid:63851304-779e-4d9b-9485-3ea1c20592b1</id>
<logo><c:url value="${props.baseUrl}/html/1/images/genesys.png" /></logo>
<logo><c:url value="${cdnServers.next}/html/1/images/genesys.png" /></logo>
<rights type="html"><spring:message code="footer.copyright-statement" /></rights>
<c:if test="${lastNews.size() gt 0}">
......@@ -22,8 +22,8 @@
<c:forEach items="${lastNews}" var="news" varStatus="status">
<entry>
<title><c:out value="${jspHelper.htmlToText(news.title)}" /></title>
<link href="<c:url value="${props.baseUrl}/content/news/${news.id}/${jspHelper.suggestUrlForText(news.title)}" />" />
<id><c:url value="${props.baseUrl}/content/news/${news.id}/#id" /></id>
<link href="<c:url value="${baseUrl}/content/news/${news.id}/${jspHelper.suggestUrlForText(news.title)}" />" />
<id><c:url value="${baseUrl}/content/news/${news.id}/#id" /></id>
<published><fmt:formatDate value="${news.postDate.time}" pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" /></published>
<updated><fmt:formatDate value="${news.lastModifiedDate == null ? news.createdDate : news.lastModifiedDate}" pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" /></updated>
<%-- <summary><c:out value="${jspHelper.htmlToText(news.body, 400)}" /></summary> --%>
......
......@@ -9,7 +9,7 @@
<body>
<h1>
<c:out value="${country.getName(pageContext.response.locale)}" />
<img class="country-flag bigger" src="<c:url value="${cdnFlagsUrl}" />/${country.code3.toUpperCase()}.svg" />
<img class="country-flag bigger" src="<local:country-flag code3="${country.code3}" />" />
</h1>
<form role="form" class="" action="<c:url value="/geo/${country.code3}/update" />" method="post">
......
......@@ -9,7 +9,7 @@
<body>
<h1>
<c:out value="${country.getName(pageContext.response.locale)}" />
<img class="country-flag bigger" src="<c:url value="${cdnFlagsUrl}/${country.code3.toUpperCase()}.svg" />" />
<img class="country-flag bigger" src="<local:country-flag code3="${country.code3}" />" />
</h1>
<div class="main-col-header">
......
......@@ -149,7 +149,7 @@
});
</script>
<script type="text/javascript" src="<c:url value="/html/1/js/genesyshighcharts.min.js" />"></script>
<script type="text/javascript" src="<c:url value="${cdnServers.next}/html/1/js/genesyshighcharts.min.js" />"></script>
<script type="text/javascript">
$(function () {
'use strict';
......