Commit 2c2abbb9 authored by Matija Obreza's avatar Matija Obreza
Browse files

Using <cms:menu (+1 squashed commit)

Squashed commits:
[9d4bf98] CMS menu, menu items using i18n from language.properties and the <cms:menu tag
parent 6389d253
......@@ -16,6 +16,7 @@
package org.genesys2.server.listener.sample;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Locale;
......@@ -26,10 +27,12 @@ import org.genesys2.server.listener.RunAsAdminListener;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.service.ContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
......@@ -55,11 +58,24 @@ import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class CreateContentListener extends RunAsAdminListener {
@Value("${auto.createContent}")
private final boolean createContent = false;
@Autowired
private ContentService contentService;
@Override
public void init() throws Exception {
createArticles();
createMenus();
}
private void createArticles() throws IOException, JsonProcessingException {
if (!createContent) {
_logger.info("Skipping menu creation on startup.");
return;
}
_logger.info("Checking if default content exists");
final ClassLoader classLoader = CreateContentListener.class.getClassLoader();
final PathMatchingResourcePatternResolver rpr = new PathMatchingResourcePatternResolver(classLoader);
......@@ -91,4 +107,28 @@ public class CreateContentListener extends RunAsAdminListener {
}
}
}
/**
* Generates CMS Menu and MenuItems
*/
private void createMenus() {
_logger.info("Checking if default menus exist");
// legal
contentService.ensureMenuItem("legal", "/content/legal/disclaimer", "menu.disclaimer");
contentService.ensureMenuItem("legal", "/content/legal/terms", "menu.terms");
contentService.ensureMenuItem("legal", "/content/legal/copying", "menu.copying");
contentService.ensureMenuItem("legal", "/content/legal/privacy", "menu.privacy");
// about
contentService.ensureMenuItem("about", "/content/about/about", "menu.about");
contentService.ensureMenuItem("about", "/content/about/contact", "menu.contact");
contentService.ensureMenuItem("about", "/content/about/what-is-genesys", "menu.what-is-genesys");
contentService.ensureMenuItem("about", "/content/about/who-uses-genesys", "menu.who-uses-genesys");
contentService.ensureMenuItem("about", "/content/about/how-to-use-genesys", "menu.how-to-use-genesys");
contentService.ensureMenuItem("about", "/content/about/history-of-genesys", "menu.history-of-genesys");
contentService.ensureMenuItem("about", "/content/about/about-genesys-data", "menu.about-genesys-data");
contentService.ensureMenuItem("about", "/content/about/genesys-newsletter", "menu.newsletter");
}
}
/**
* Copyright 2015 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.model.impl;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import org.genesys2.server.model.BusinessModel;
/**
* CMS Menu.
*/
@Entity
@Table(name = "cmsmenu")
public class Menu extends BusinessModel {
private static final long serialVersionUID = 8077072929931470029L;
@Column(name = "menukey", length = 30, unique = true)
private String key;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "menu")
@OrderBy("orderIndex")
private List<MenuItem> items = new ArrayList<MenuItem>();
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public List<MenuItem> getItems() {
return items;
}
public void setItems(List<MenuItem> items) {
this.items = items;
}
}
/**
* Copyright 2015 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.model.impl;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.genesys2.server.model.VersionedAuditedModel;
/**
* CMS MenuItem.
*
* @author mobreza
*/
@Entity
@Table(name = "cmsmenuitem")
public class MenuItem extends VersionedAuditedModel {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -2851932999726435674L;
/**
* MenuItems in a {@link Menu} are ordered by orderIndex
*/
private float orderIndex = 10f;
/** Menu item display text, a translation code */
private String text;
/** Menu item title, a translation code */
private String title;
/** Destination URL */
private String url;
/** Target window */
private String target;
/** Parent menu **/
@ManyToOne(optional = false)
@JoinColumn(name = "menuId")
private Menu menu;
public float getOrderIndex() {
return orderIndex;
}
public void setOrderIndex(float orderIndex) {
this.orderIndex = orderIndex;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public Menu getMenu() {
return menu;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
}
/**
* Copyright 2015 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.persistence.domain;
import org.genesys2.server.model.impl.MenuItem;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MenuItemRepository extends JpaRepository<MenuItem, Long> {
}
/**
* Copyright 2015 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.persistence.domain;
import org.genesys2.server.model.impl.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MenuRepository extends JpaRepository<Menu, Long> {
Menu findByKey(String key);
}
......@@ -25,6 +25,8 @@ import org.genesys2.server.model.EntityId;
import org.genesys2.server.model.impl.ActivityPost;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.ClassPK;
import org.genesys2.server.model.impl.Menu;
import org.genesys2.server.model.impl.MenuItem;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
......@@ -111,4 +113,10 @@ public interface ContentService {
String processTemplate(String body, Map<String, Object> root);
void processTemplate(String templateStr, Map<String, Object> root, Writer writer);
Menu getMenu(String key);
Menu updateMenu(String key, List<MenuItem> menuItems);
MenuItem ensureMenuItem(String menuKey, String url, String text);
}
......@@ -32,9 +32,13 @@ import org.genesys2.server.model.EntityId;
import org.genesys2.server.model.impl.ActivityPost;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.ClassPK;
import org.genesys2.server.model.impl.Menu;
import org.genesys2.server.model.impl.MenuItem;
import org.genesys2.server.persistence.domain.ActivityPostRepository;
import org.genesys2.server.persistence.domain.ArticleRepository;
import org.genesys2.server.persistence.domain.ClassPKRepository;
import org.genesys2.server.persistence.domain.MenuItemRepository;
import org.genesys2.server.persistence.domain.MenuRepository;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.HtmlSanitizer;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -68,6 +72,12 @@ public class ContentServiceImpl implements ContentService {
@Autowired
private VelocityEngine velocityEngine;
@Autowired
private MenuRepository repoMenu;
@Autowired
private MenuItemRepository repoMenuItem;
@Override
public Locale getDefaultLocale() {
// TODO FIXME We should use a configurable default locale for content
......@@ -345,4 +355,99 @@ public class ContentServiceImpl implements ContentService {
*/
velocityEngine.evaluate(context, writer, "log tag name", templateStr);
}
/**
* Load/get the CMS menu specified by the key
*
* @param key
* @return
*/
@Override
@Cacheable(value = "contentcache", key = "'menu-' + #key", unless = "#result == null")
public Menu getMenu(String key) {
Menu menu = repoMenu.findByKey(key);
if (menu != null) {
menu.getItems().size();
}
return menu;
}
/**
* Ensure the CMS menu item exists in the menu
*
* @return
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@CacheEvict(value = "contentcache", allEntries = true)
public MenuItem ensureMenuItem(String menuKey, String url, String text) {
Menu menu = repoMenu.findByKey(menuKey);
if (menu == null) {
// Create instance
menu = new Menu();
menu.setKey(menuKey);
repoMenu.save(menu);
}
for (MenuItem item : menu.getItems()) {
if (StringUtils.equals(item.getUrl(), url)) {
LOG.debug("Found menu item with URL " + url);
return item;
}
}
LOG.info("Creating menu item with URL " + url);
MenuItem item = new MenuItem();
item.setMenu(menu);
item.setUrl(url);
item.setText(text);
item.setOrderIndex(menu.getItems().size());
menu.getItems().add(item);
repoMenuItem.save(item);
return item;
}
/**
* Update the CMS menu specified by key with the provided structure
*
* @param key
* @param items
* @return
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@CacheEvict(value = "contentcache", allEntries = true)
public Menu updateMenu(String menuKey, List<MenuItem> items) {
Menu menu = repoMenu.findByKey(menuKey);
if (items.size() == 0) {
if (menu != null) {
LOG.info("Deleting CMS menu " + menuKey);
// Should delete all menu items
repoMenu.delete(menu);
} else {
// NOOP
LOG.info("Unknown CMS menu " + menuKey);
}
return null;
}
if (menu == null) {
// Create instance
menu = new Menu();
menu.setKey(menuKey);
}
// TODO Remove items missing from the List
// TODO Add items in the list missing from the menu
// TODO Persist.
return menu;
}
}
......@@ -206,6 +206,14 @@ public class ArticleController extends BaseController {
return "/content/article";
}
@RequestMapping("{menu}/{url:.+}")
public String viewWithMenu(ModelMap model, @PathVariable(value = "menu") String menuKey, @PathVariable(value = "url") String slug) {
view(model, slug);
_logger.debug("Loading menu " + menuKey);
model.addAttribute("menu", contentService.getMenu(menuKey));
return "/content/article";
}
/**
* Edit article in current language
......
......@@ -76,7 +76,7 @@ i18n.content-not-translated=This content is not available in your language. Plea
data.error.404=The data you requested was not found in the system.
page.rendertime=Processing this page took {0}ms.
footer.copyright-statement=&copy; 2013 Data Providers and GCDT
footer.copyright-statement=&copy; 2013 - 2015 Data Providers and the Crop Trust
menu.home=Home
menu.browse=Browse
......@@ -85,21 +85,32 @@ menu.descriptors=Descriptors
menu.countries=Countries
menu.institutes=Institutes
menu.my-list=My List
menu.about=About
menu.contact=Contact
menu.about=About Genesys
menu.contact=Contact Us
menu.disclaimer=Disclaimer
menu.feedback=Feedback
menu.help=Help
menu.terms=Terms and Conditions of Use
menu.copying=Copyright policy
menu.privacy=Privacy policy
menu.newsletter=Genesys Newsletter
menu.join-the-community=Join the Genesys Community
# Extra content
menu.what-is-genesys=What is Genesys?
menu.who-uses-genesys=Who uses Genesys?
menu.how-to-use-genesys=How to use Genesys?
menu.history-of-genesys=History of Genesys
menu.about-genesys-data=About Genesys data
page.home.title=Genesys PGR
user.pulldown.administration=Administration
user.pulldown.users=User list
user.pulldown.logout=Logout
user.pulldown.profile=View profile
user.pulldown.profile=My profile
user.pulldown.oauth-clients=OAuth clients
user.pulldown.teams=Teams
......
......@@ -7,18 +7,18 @@
<div class="container">
<div id="nav-foot" class="clearfix">
<ul class="nav pull-left">
<li><a href="<c:url value="/content/about" />"><spring:message code="menu.about" /></a></li>
<li><a href="<c:url value="/content/contact" />"><spring:message code="menu.contact" /></a></li>
<li><a href="<c:url value="/content/disclaimer" />"><spring:message code="menu.disclaimer" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><spring:message code="menu.about" /></a></li>
<li><a href="<c:url value="/content/about/contact" />"><spring:message code="menu.contact" /></a></li>
<li><a href="<c:url value="/content/legal/disclaimer" />"><spring:message code="menu.disclaimer" /></a></li>
<li><a target="_blank" href="https://bitbucket.org/genesys2/genesys2-server/issues/new"><spring:message code="menu.report-an-issue" /></a></li>
<li class="notimportant"><a target="_blank" href="https://bitbucket.org/genesys2/genesys2-server.git"><spring:message code="menu.scm" /></a></li>
<li class="notimportant"><a target="_blank" href="https://www.transifex.com/projects/p/genesys/"><spring:message code="menu.translate" /></a></li>
</ul>
<ul class="nav pull-right">
<li><a href="<c:url value="/content/terms" />"><spring:message code="menu.terms" /></a></li>
<li><a href="<c:url value="/content/copying" />"><spring:message code="menu.copying" /></a></li>
<li><a href="<c:url value="/content/privacy" />"><spring:message code="menu.privacy" /></a></li>
<li><a href="<c:url value="/content/legal/terms" />"><spring:message code="menu.terms" /></a></li>
<li><a href="<c:url value="/content/legal/copying" />"><spring:message code="menu.copying" /></a></li>
<li><a href="<c:url value="/content/legal/privacy" />"><spring:message code="menu.privacy" /></a></li>
</ul>
</div>
<div class="pull-left" id="copyright">
......
......@@ -6,22 +6,15 @@
<ul class="nav navbar-nav">
<li class="notimportant"><a href="<c:url value="/welcome" />"><spring:message code="menu.home" /></a></li>
<li class="dropdown">
<a href="<c:url value="/content/about" />" class="dropdown-toggle" data-toggle="dropdown"><spring:message code="menu.about" />
<%--
<i class="fa fa-caret-down"></i><i class="fa fa-caret-up"></i>
--%>
</a>
<a href="<c:url value="/content/about" />" class="dropdown-toggle" data-toggle="dropdown"><spring:message code="menu.about" /></a>
<ul class="dropdown-menu about">
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.about" /></a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> what is genesys?</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> who uses genesys?</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> how to use genesys?</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> history of genesys</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> about genesys data</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> genesys newtork</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> genesys news</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> my genesys</a></li>
<li><a href="<c:url value="/content/about" />"><i class="fa fa-caret-right"></i> contact us</a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.about" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.what-is-genesys" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.who-uses-genesys" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.how-to-use-genesys" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.history-of-genesys" /></a></li>
<li><a href="<c:url value="/content/about/about" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.about-genesys-data" /></a></li>
<li><a href="<c:url value="/content/about/contact" />"><i class="fa fa-caret-right"></i> <spring:message code="menu.contact" /></a></li>
</ul>
</li>
<li><a href="<c:url value="/explore" />"><spring:message code="menu.browse" /></a></li>
......
......@@ -38,6 +38,10 @@
<c:out value="${article.body}" escapeXml="false" />
<div class="clearfix pull-right">
<fmt:formatDate value="${article.postDate.time}" />
</div>
<%-- <div class="share-article">
<p><spring:message code="article.share" /></p>
<ul class="list-inline">
......@@ -66,39 +70,11 @@
<div class="col-md-3 sidebar-nav col-xs-12">
<ul class="list-unstyled">
<li>
<a href="<c:url value="/content/disclaimer" />">
<spring:message code="menu.disclaimer" />
</a>
</li>
<li>
<a href="<c:url value="/content/terms" />">
<spring:message code="menu.terms" />