From 8e98850493fb10d63504833d15e23d2a81f6dbaa Mon Sep 17 00:00:00 2001 From: hjkhjk54 Date: Wed, 16 May 2012 21:13:33 +0000 Subject: [PATCH] updates for page management --- .../freemarker/BaseSiteAdminController.java | 2 + .../generators/ManagePageGenerator.java | 310 ++++++++++++++++++ webapp/web/css/menupage/pageList.css | 5 + webapp/web/css/menupage/pageManagement.css | 19 ++ webapp/web/images/checkMark.png | Bin 0 -> 283 bytes webapp/web/images/individual/arrow-up.gif | Bin 0 -> 179 bytes webapp/web/js/menupage/pageManagementUtils.js | 295 +++++++++++++++++ .../body/pagemanagement/page-pageList.ftl | 32 ++ .../body/pagemanagement/pageList.ftl | 63 ++++ .../siteAdmin/siteAdmin-siteConfiguration.ftl | 6 +- .../freemarker/edit/forms/pageManagement.ftl | 157 +++++++++ 11 files changed, 888 insertions(+), 1 deletion(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java create mode 100644 webapp/web/css/menupage/pageList.css create mode 100644 webapp/web/css/menupage/pageManagement.css create mode 100644 webapp/web/images/checkMark.png create mode 100644 webapp/web/images/individual/arrow-up.gif create mode 100644 webapp/web/js/menupage/pageManagementUtils.js create mode 100644 webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl create mode 100644 webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl create mode 100644 webapp/web/templates/freemarker/edit/forms/pageManagement.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java index 5ed66765a..b1baf2481 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java @@ -130,10 +130,12 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet { data.put("siteInfo", UrlBuilder.getUrl("/editForm", "controller", "ApplicationBean")); } + //TODO: Add specific permissions for page management if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.MANAGE_MENUS.ACTIONS)) { data.put("menuManagement", UrlBuilder.getUrl("/individual", "uri", "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#DefaultMenu", "switchToDisplayModel", "true")); + data.put("pageManagement", UrlBuilder.getUrl("/pageList")); } if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.SEE_STARTUP_STATUS.ACTIONS)) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java new file mode 100644 index 000000000..9496c2aa0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java @@ -0,0 +1,310 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeIntervalValidationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.DateTimeWithPrecisionVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; + + +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.vocabulary.OWL; +import com.hp.hpl.jena.vocabulary.RDF; +import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.vocabulary.XSD; +import com.hp.hpl.jena.ontology.OntModel; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.ChildVClassesOptions; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.SelectListGeneratorVTwo; +import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils; +import edu.cornell.mannlib.vitro.webapp.utils.menuManagement.MenuManagementDataUtils; +import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils; +import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; + +/** + * Generates the form for adding and editing a page in the display model. + * + */ +public class ManagePageGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator{ + + private String template = "pageManagement.ftl"; + + @Override + public EditConfigurationVTwo getEditConfiguration( VitroRequest vreq, HttpSession session) { + EditConfigurationVTwo conf = new EditConfigurationVTwo(); + conf.setTemplate(template); + + //get editkey and url of form + initBasics(conf, vreq); + initPropertyParameters(vreq, session, conf); + //if object uri exists, sets object URI + initObjectPropForm(conf, vreq); + //Depending on whether this is a new individual to be created or editing + //an existing one, the var names will differ + setVarNames(conf); + //Set N3 required and optional + setN3Required(conf); + setN3Optional(conf); + + //Designate new resources if any exist + setNewResources(conf); + + //Add sparql queries + setSparqlQueries(conf); + //Set the fields + setFields(conf); + + //Adding additional data, specifically edit mode + addFormSpecificData(conf, vreq); + //Prepare + prepare(vreq, conf); + + return conf ; + } + + private void setN3Optional(EditConfigurationVTwo conf) { + //body template is not required, and a given page may or may not be a menu item, but should linked to menu if menu item + conf.setN3Optional(Arrays.asList(prefixes + pageBodyTemplateN3, + prefixes + menuItemN3 + menuN3)); + } + + private void setN3Required(EditConfigurationVTwo conf) { + conf.setN3Required(Arrays.asList(prefixes + pageN3)); + + } + + private void setFields(EditConfigurationVTwo conf) { + //Required fields for page include: Page title, page URL Mapping + //Data getter fields will be dealt with in preprocessor/util classes + //Optional fields for page include body template + + //required, therefore nonempty + FieldVTwo titleField = new FieldVTwo().setName("pageTitle"). + setValidators(Arrays.asList("nonempty")); + conf.addField(titleField); + + FieldVTwo urlField = new FieldVTwo().setName("urlMapping").setValidators(Arrays.asList("nonempty")); + conf.addField(urlField); + + //optional: body template + FieldVTwo bodyTemplateField = new FieldVTwo().setName("bodyTemplate"); + conf.addField(bodyTemplateField); + + + //For menu item, these are optional b/c they depend on menu item + FieldVTwo menuItemLinkTextField = new FieldVTwo().setName("linkText"); + conf.addField(menuItemLinkTextField); + + FieldVTwo menuItemPositionField = new FieldVTwo().setName("menuPosition"); + conf.addField(menuItemPositionField); + } + + + + private void setVarNames(EditConfigurationVTwo conf) { + if(conf.getSubjectUri() != null) { + conf.setVarNameForSubject("page"); + conf.setVarNameForPredicate("predicate"); + } else { + conf.setVarNameForSubject("subjectNotUsed"); + conf.setVarNameForPredicate("predicateNotUsed"); + } + + } + + //overriding + @Override + void initPropertyParameters(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { + + String subjectUri = EditConfigurationUtils.getSubjectUri(vreq); + String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); + + //For the case of a new page + if(subjectUri == null) { + //Once added, return to pageList + editConfiguration.setUrlToReturnTo("/pageList"); + editConfiguration.setEntityToReturnTo("?page"); + editConfiguration.setPredicateUri(predicateUri); + + } else { + //For the case of an existing page + //Page title pageTitle or page hasDataGetter dataGetter + editConfiguration.setUrlPatternToReturnTo("/individual"); + editConfiguration.setEntityToReturnTo(subjectUri); + } + editConfiguration.setSubjectUri(subjectUri); + editConfiguration.setPredicateUri(predicateUri); + } + + + //also overriding + @Override + void prepare(VitroRequest vreq, EditConfigurationVTwo editConfig) { + //setup the model selectors for query, write and display models on editConfig + //Double-check if this will even work with over-written model in the case of display model? + setupModelSelectorsFromVitroRequest(vreq, editConfig); + OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + + if (editConfig.getSubjectUri() != null) { + editConfig.prepareForObjPropUpdate(queryModel); + } + else{ + //if no subject uri, this is creating a new page + editConfig.prepareForNonUpdate(queryModel); + } + } + + + //In the case where this is a new page, need to ensure page gets a new + private void setNewResources(EditConfigurationVTwo conf) { + //null makes default namespace be triggered + conf.addNewResource("page", DEFAULT_NS_FOR_NEW_RESOURCE); + conf.addNewResource("menuItem", DEFAULT_NS_FOR_NEW_RESOURCE); + + } + + //This is for various items + private void setSparqlQueries(EditConfigurationVTwo editConfiguration) { + //Sparql queries defining retrieval of literals etc. + editConfiguration.setSparqlForAdditionalLiteralsInScope(new HashMap()); + + Map urisInScope = new HashMap(); + editConfiguration.setSparqlForAdditionalUrisInScope(urisInScope); + + editConfiguration.setSparqlForExistingLiterals(generateSparqlForExistingLiterals()); + editConfiguration.setSparqlForExistingUris(generateSparqlForExistingUris()); + } + + + //Get page uri for object + private HashMap generateSparqlForExistingUris() { + HashMap map = new HashMap(); + return map; + } + + private HashMap generateSparqlForExistingLiterals() { + HashMap map = new HashMap(); + return map; + } + + + + + + //Form specific data + //In this case, need to get all the different data getter TYPES and labels + //Also need to pass back the map for the options presented to the user + //which is different from the above + //Maybe mapping where it does exist? I.e. sparql query from drop-down IS sparql query data getter + //Class group is hard-coded to class group but otherwise it can be changed + //Based on circumstances - specifically internal class data getter + //Need to get the hash for data getter to label TO the form so + //that can then be read by javascript? + //Also pass back current menu position? + public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) { + HashMap formSpecificData = new HashMap(); + //Get options for user: label to data getter type + //For every type of page, will need some "always required" data + addRequiredPageData(vreq, formSpecificData); + //For a new page, we will need to add the following data + addNewPageData(vreq, formSpecificData); + + editConfiguration.setFormSpecificData(formSpecificData); + } + + private String getTemplate(EditConfigurationVTwo editConfiguration) { + String returnTemplate = "default"; + if(editConfiguration.getSubjectUri() != null) { + //Then template is EXISTING template + //TODO: Get existing template value for page + } + return returnTemplate; + + } + + private void addRequiredPageData(VitroRequest vreq, Map data) { + MenuManagementDataUtils.includeRequiredSystemData(vreq.getSession().getServletContext(), data); + } + + private void addNewPageData(VitroRequest vreq, Map data) { + data.put("title", "Add Menu Item"); + data.put("menuAction", "Add"); + //Generate empty values for fields + data.put("menuItem", ""); + data.put("menuName", ""); + data.put("prettyUrl", ""); + data.put("associatedPage", ""); + data.put("associatedPageURI", ""); + data.put("classGroup", new ArrayList()); + //not a page already assigned a class group + data.put("isClassGroupPage", false); + data.put("includeAllClasses", false); + data.put("classGroups", DataGetterUtils.getClassGroups(vreq.getSession().getServletContext())); + data.put("selectedTemplateType", "default"); + //defaults to regular class group page + } + + //N3 strings + + //For new or existing page + final static String prefixes = "@prefix display: . \n" + + "@prefix rdfs: . \n"; + + final static String pageN3 = "?page a display:Page ; \n" + + "display:title ?pageTitle ;\n" + + "display:urlMapping ?urlMapping ."; + + //"display:hasDataGetter ?pageDataGetter ."; + + //A page may also require a body template so we can get that here as well + //That would be optional + + final static String pageBodyTemplateN3 = "?page display:requiresBodyTemplate ?bodyTemplate ."; + + //Menu position is added dynamically at end by default and can be changed on reordering page + final static String menuItemN3 = "?menuItem a display:NavigationElement ; \n" + + "display:menuPosition ?menuPosition; \n" + + "display:linkText ?menuLinkText; \n" + + "display:toPage ?page ."; + + //We define n3 here from default menu item up through page, but data getters are added dyamically + //so will be dealt with in the preprocessor + + final static String menuN3 = "display:DefaultMenu display:hasElement ?menuItem ."; + + //These are public static methods that can be used in the preprocessor + public final static String getDataGetterN3(int numberDataGetter) { + return prefixes + "?page display:hasDataGetter ?dataGetter" + numberDataGetter + "."; + } + + +} diff --git a/webapp/web/css/menupage/pageList.css b/webapp/web/css/menupage/pageList.css new file mode 100644 index 000000000..7b124d062 --- /dev/null +++ b/webapp/web/css/menupage/pageList.css @@ -0,0 +1,5 @@ +.menuFlag { + width:67px; + height:18px; + background: url("../../images/checkMark.png") no-repeat left center; +} \ No newline at end of file diff --git a/webapp/web/css/menupage/pageManagement.css b/webapp/web/css/menupage/pageManagement.css new file mode 100644 index 000000000..7052c6d05 --- /dev/null +++ b/webapp/web/css/menupage/pageManagement.css @@ -0,0 +1,19 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +.pageContent {"background-color":"","padding-left":"","padding-top":"","border-width":"","border-style":"","border-color":"#ccc"} + +.pageContentContainer {background-color:#f5f5f5;border-color:#ccc;border-width:1px;border-style:solid;margin-bottom:4px;} + +.pageContentTypeLabel {padding-left:6px;} + +.pageContentWrapper {background-color:#f9f9f9;padding-left:6px;padding-top:2px;border-top-width:1px;border-style:solid;border-color:#ccc;} + +.pageContentExpand {float:right;padding-right:5px;} + +.arrow { + width:13px; height:9px; display:block; +} +.expandArrow {background-image:url(../../images/individual/arrow-down.gif);} +.collapseArrow {background-image:url(../../images/individual/arrow-up.gif);} + +.deleteButton{margin-bottom:5px;} \ No newline at end of file diff --git a/webapp/web/images/checkMark.png b/webapp/web/images/checkMark.png new file mode 100644 index 0000000000000000000000000000000000000000..197767db213bb072f4028486057fdec1ebfcdc62 GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Y)RhkE)4%c zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPav$QC?-h)?anm{3?64!_l=ltB< z)VvY~=c3falGGH1^30M91$R&10EPTKg+vA4#N_rB<<3CWxt=bLAr`04Uh(ESpuod& zVI#-E-|}IbR;~8RNS3wd-s~smY|yr*D%m;qMo7AYCyQqaZ&kxm7qOG8iYK)5IP0cx z{Bq7%(azxT#?;8eH%0o5LN|lMhV9?#q;)>soM?VP;oYXU3f)&y&o8t1Ev@-A-{d6w T=alzAiy1s!{an^LB{Ts5n^avA literal 0 HcmV?d00001 diff --git a/webapp/web/images/individual/arrow-up.gif b/webapp/web/images/individual/arrow-up.gif new file mode 100644 index 0000000000000000000000000000000000000000..57ca5bc01261f0f6a0cf854e2aa5e69ad74905fa GIT binary patch literal 179 zcmZ?wbhEHbyB@yX_vqb$ zXCF?z`Eu>;mzzI+zyJCB<9`x?;!hSv1_pTs9R?r(*~!3a@Ibw*<3P`f84L{", { + id: "divContainer" + counter, + "class": "pageContentContainer", + html: "" + contentTypeLabel + " - " + varOrClass + + "
" + }); + var $clickableSpan = $newDivContainer.children('span#clickable' + counter); + var $innerDiv = $newDivContainer.children('div#innerContainer' + counter); + $innerDiv.hide(); + //Expand/collapse toggle + $clickableSpan.click(function() { + if ( $innerDiv.is(':visible') ) { + $innerDiv.slideUp(222); + //$clickableSpan.find('img').attr("src","arrow-down.gif"); + var arrowDiv = $clickableSpan.find('div.arrow'); + arrowDiv.removeClass("collapseArrow"); + arrowDiv.addClass("expandArrow"); + } + else { + $innerDiv.slideDown(222); + //$clickableSpan.find('img').attr("src","arrow-up.gif"); + var arrowDiv = $clickableSpan.find('div.arrow'); + arrowDiv.removeClass("expandArrow"); + arrowDiv.addClass("collapseArrow"); + } + window.setTimeout('pageManagementUtils.adjustSaveButtonHeight()', 223); + }); + $newRemoveButton = $innerDiv.find('input#remove' + counter); + // this will have to disable submitted fields as well as hide them. + $newRemoveButton.click(function() { + $innerDiv.parent("div").css("display","none"); + pageManagementUtils.adjustSaveButtonHeight(); + }); + + $newDivContainer.appendTo($('section#contentDivs')); + $newContentObj.prependTo($innerDiv); + counter = counter + 10; + }, + resetClassGroupSection:function() { + $('select#selectClassGroup option').eq(0).attr('selected', 'selected'); + $("section#classesInSelectedGroup").addClass('hidden'); + }, + //finalize later, but basically use same attribute across page content and use attribute instead of id + //Attribute would be what keeps track of content, so contentCounter or something like that + toggleArrow:function() { + + + }, + //Adjust save button height + adjustSaveButtonHeight:function() { + if ( $("div#leftSide").css("height") != undefined ) { + $("div#leftSide").css("height",""); + if ( $("div#leftSide").height() < $("div#rightSide").height() ) { + $("div#leftSide").css("height",$("div#rightSide").height() + "px"); + } + } + } + +}; + +$(document).ready(function() { + pageManagementUtils.onLoad(); +}); \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl b/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl new file mode 100644 index 000000000..8553f4816 --- /dev/null +++ b/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl @@ -0,0 +1,32 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +
+ +<#if pages?has_content > + + + + <#list pages as pagex> + + + <#if pagex.pageUri??> + + <#else> + + + + +
TitleURI
${(pagex.title)!'-untitled-'}${pagex.pageUri}URI for page not defined
+ +<#else> +

There are no pages defined yet.

+ + +
+ + + + +
+ +
\ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl new file mode 100644 index 000000000..1230695fb --- /dev/null +++ b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl @@ -0,0 +1,63 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +
+
+

Page Management

+
+
+ + +<#if pages?has_content > + + + + + + + + + + + + + + <#list pages as pagex> + + + + + + + + + + + +
Page Management
TitleURLTemplateMenu Page
+ <#if pagex.pageUri?has_content> + ${(pagex.title)!'-untitled-'} + <#else> + No URI defined for page. + + ${pagex.urlMapping}${(pagex.template)!''} + <#if pagex.menuItem?has_content> + + +
+ +<#else> +

There are no pages defined yet.

+ + +
+ + + + +
+

Use Menu Management to set the order of menu items.

+
+ + +${stylesheets.add('')} + diff --git a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl index 4f96db431..db2e20f98 100644 --- a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl +++ b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl @@ -13,7 +13,11 @@ <#if siteConfig.manageProxies?has_content>
  • Manage profile editing
  • - + + + <#if siteConfig.pageManagement?has_content> +
  • Page management
  • + <#if siteConfig.menuManagement?has_content>
  • Menu management
  • diff --git a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl new file mode 100644 index 000000000..c8d6a68e0 --- /dev/null +++ b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl @@ -0,0 +1,157 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> +<#--Set up variables--> +<#assign pageData = editConfiguration.pageData /> +<#assign menuAction = pageData.menuAction /> +<#assign classGroup = pageData.classGroup /> +<#assign classGroups = pageData.classGroups /> + +<#assign selectedTemplateType = "default" /> +<#assign menuItem = ""/> +<#assign menuName = ""/> +<#assign prettyUrl = ""/> +<#assign associatedPage = ""/> +<#assign associatedPageURI = ""/> + +<#assign isClassGroupPage = false/> +<#assign includeAllClasses = false/> + + +<#-- some additional processing here which shows or hides the class group selection and classes based on initial action--> +<#assign existingClassGroupStyle = " " /> +<#assign selectClassGroupStyle = 'class="hidden"' /> +<#-- Reveal the class group and hide the class selects if adding a new menu item or editing an existing menu item with an empty class group (no classes)--> +<#if menuAction == "Add" || !classGroup?has_content> + <#assign existingClassGroupStyle = 'class="hidden"' /> + <#assign selectClassGroupStyle = " " /> + + + +<#--class group section has associated page uri, but that depends on editing a current page or if one is selected later--> +
    +

    Add Page

    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + + +
    +
    + <#-- Select classes in a class group --> +

    Select content to display *

    + + <#include "pageManagement--classIntersections.ftl"> + + +
    +
    +
    + + + + +
    + +
    +
    +
    +
    + + + + +

    Must begin with a leading forward slash: / (e.g., /people)

    +

    Template *

    + checked role="radio" /> + +
    + checked role="input" /> + +
    class="hidden" role="region"> + * +
    +

    This is a menu page

    + +
    +
    +
    +
    + or + Cancel +
    +

    * required fields

    +
    +
    + + + + +${stylesheets.add('')} +${stylesheets.add('')} +${stylesheets.add('')} + +${scripts.add('')} +${scripts.add('')} +${scripts.add('')} +${scripts.add('')} +