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 index 2b3dfad09..ac0cd78c4 100644 --- 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 @@ -98,7 +98,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen private void setUrisAndLiteralsOnForm(EditConfigurationVTwo conf, VitroRequest vreq) { conf.setUrisOnForm(new String[]{"page", "menuItem"}); //new resources: should this be on form for new - should be for existing - conf.setLiteralsOnForm(new String[]{"pageName", "prettyUrl", "menuPosition", "menuLinkText", "customTemplate", "pageContentUnit"}); //page content unit = data getter JSON object + conf.setLiteralsOnForm(new String[]{"pageName", "prettyUrl", "menuPosition", "menuLinkText", "customTemplate", "isSelfContainedTemplate", "pageContentUnit"}); //page content unit = data getter JSON object } @@ -116,7 +116,8 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen 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(new ArrayList(Arrays.asList(prefixes + pageBodyTemplateN3, - prefixes + menuItemN3 + menuN3))); + prefixes + menuItemN3 + menuN3, + prefixes + isSelfContainedTemplateN3))); } private void setN3Required(EditConfigurationVTwo conf) { @@ -149,6 +150,10 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen FieldVTwo menuItemPositionField = new FieldVTwo().setName("menuPosition").setRangeDatatypeUri(XSD.integer.getURI()); conf.addField(menuItemPositionField); + //If this is a self contained template, the appropriate flag will be set + FieldVTwo isSelfContainedTemplateField = new FieldVTwo().setName("isSelfContainedTemplate"); + conf.addField(isSelfContainedTemplateField); + //The actual page content information is stored in this field, and then //interpreted using the preprocessor FieldVTwo pageContentUnitField = new FieldVTwo().setName("pageContentUnit"); @@ -423,6 +428,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen map.put("menuPosition", getExistingMenuPositionQuery()); map.put("menuLinkText", getExistingMenuLinkTextQuery()); map.put("customTemplate", getExistingCustomTemplateQuery()); + map.put("isSelfContainedTemplate", getExistingIsSelfContainedTemplateQuery()); return map; } @@ -462,6 +468,12 @@ private String getExistingCustomTemplateQuery() { return query; } +private String getExistingIsSelfContainedTemplateQuery() { + String query = getSparqlPrefix() + "SELECT ?isSelfContainedTemplate WHERE {?page display:isSelfContainedTemplate ?isSelfContainedTemplate .}"; + + return query; +} + //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 @@ -533,6 +545,10 @@ private String getExistingCustomTemplateQuery() { final static String pageBodyTemplateN3 = "?page display:requiresBodyTemplate ?customTemplate ."; + //If self contained template, n3 will denote this using a flag + final static String isSelfContainedTemplateN3 = "?page display:isSelfContainedTemplate ?isSelfContainedTemplate ."; + + //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" + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ManagePagePreprocessor.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ManagePagePreprocessor.java index 41520c592..be1b1ce4c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ManagePagePreprocessor.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/ManagePagePreprocessor.java @@ -172,11 +172,14 @@ public class ManagePagePreprocessor extends private void convertToJson() { //Iterate through list of inputs pageContentUnitsJSON = new ArrayList(); - for(String pageContentUnit: pageContentUnits) { - JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( pageContentUnit ); - pageContentUnitsJSON.add(jsonObject); + //page content units might return null in case self-contained template is selected + //otherwise there should be page content units returned from the form + if(pageContentUnits != null) { + for(String pageContentUnit: pageContentUnits) { + JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( pageContentUnit ); + pageContentUnitsJSON.add(jsonObject); + } } - } //This is where the actual values will be submitted as if they were separate input fields diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessFixedHTMLN3.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessFixedHTMLN3.java index c1bd72c99..ae6cabdaa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessFixedHTMLN3.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessFixedHTMLN3.java @@ -142,8 +142,11 @@ public class ProcessFixedHTMLN3 extends ProcessDataGetterAbstract { QuerySolution qs = results.nextSolution(); Literal saveToVarLiteral = qs.getLiteral("saveToVar"); Literal htmlValueLiteral = qs.getLiteral("htmlValue"); + String htmlValueString = htmlValueLiteral.getString(); + htmlValueString = this.replaceQuotes(htmlValueString); jObject.element("saveToVar", saveToVarLiteral.getString()); - jObject.element("htmlValue", htmlValueLiteral.getString()); + //TODO: Handle single and double quotes within string and escape properlyu + jObject.element("htmlValue", htmlValueString); } } catch(Exception ex) { log.error("Exception occurred in retrieving existing values with query " + querystr, ex); @@ -151,6 +154,12 @@ public class ProcessFixedHTMLN3 extends ProcessDataGetterAbstract { return jObject; } + + //Escape single and double quotes for html string to be returned to form + public String replaceQuotes(String inputStr) { + return inputStr.replaceAll("\'", "'").replaceAll("\"", """); + + } } diff --git a/webapp/web/WEB-INF/ontologies/app/menuload/displayTBOX.n3 b/webapp/web/WEB-INF/ontologies/app/menuload/displayTBOX.n3 index 0b202e6bc..0fc93da2c 100644 --- a/webapp/web/WEB-INF/ontologies/app/menuload/displayTBOX.n3 +++ b/webapp/web/WEB-INF/ontologies/app/menuload/displayTBOX.n3 @@ -91,6 +91,9 @@ owl:versionInfo a owl:DatatypeProperty . + + a owl:DatatypeProperty . + a owl:DatatypeProperty ; diff --git a/webapp/web/js/menupage/pageManagementUtils.js b/webapp/web/js/menupage/pageManagementUtils.js index b134b3b47..f44ef2dfa 100644 --- a/webapp/web/js/menupage/pageManagementUtils.js +++ b/webapp/web/js/menupage/pageManagementUtils.js @@ -256,7 +256,7 @@ var pageManagementUtils = { var validationError = pageManagementUtils.validateMenuItemForm(); //Add any errors from page content sections if necessary // Only validate the content sections if the self contained template section is NOT selected tlw72 - if ( !pageManagementUtils.selfContainedTemplate.is(':checked') ) { + if ( !pageManagementUtils.isSelfContainedTemplateChecked() ) { validationError += pageManagementUtils.validatePageContentSections(); } if (validationError == "") { @@ -264,7 +264,8 @@ var pageManagementUtils = { pageManagementUtils.checkMenuTitleSubmission(); //Create the appropriate json objects if necessary pageManagementUtils.createPageContentForSubmission(); - pageManagementUtils.mapCustomTemplateName(); + //pageManagementUtils.mapCustomTemplateName(); + pageManagementUtils.setUsesSelfContainedTemplateInput(); return true; } else{ $('#error-alert').removeClass('hidden'); @@ -698,10 +699,22 @@ var pageManagementUtils = { //Create a new hidden input with a specific name and assign value per page content pageManagementUtils.createPageContentInputForSubmission(jsonObjectString); }); - + //For the case where the template only selection is picked, there will be + //no page contents, but the hidden input still needs to be created as it is expected + //to exist by the edit configuration, this creates the hidden input with an empty value + if (pageManagementUtils.isSelfContainedTemplateChecked() ) { + //An empty string as no content selected + pageManagementUtils.createPageContentInputForSubmission(""); + } }, createPageContentInputForSubmission: function(inputValue) { - $("").appendTo(pageManagementUtils.pageContentSubmissionInputs); + //Previously, this code created the hidden input and included the value inline + //but this was converting html encoding for quotes/single quotes into actual quotes + //which prevented correct processing as the html thought the string had ended + //Creating the input and then using the val() method preserved the encoding + var pageContentUnit = $(""); + pageContentUnit.val(inputValue); + pageContentUnit.appendTo(pageManagementUtils.pageContentSubmissionInputs); }, //returns a json object with the data getter information required processPageContentSection:function(pageContentSection) { @@ -776,8 +789,9 @@ var pageManagementUtils = { validationError += "The pretty URL must begin with a leading forward slash
"; } - // Check custom template - if ($('input:radio[name=selectedTemplate]:checked').val() == "custom") { + // Check custom template and self contained template + var selectedTemplateValue = $('input:radio[name=selectedTemplate]:checked').val(); + if (selectedTemplateValue == "custom" || selectedTemplateValue == "selfContained") { if ($('input[name=customTemplate]').val() == "") { validationError += "You must supply a template
"; } @@ -817,17 +831,27 @@ var pageManagementUtils = { //If the selfContained-template radio is checked, copy the custom template name to the hidden //selfContainedTemplate input element. We need that for edit mode to select the correct radio button. mapCustomTemplateName:function() { - if ( this.selfContainedTemplateRadio.is(':checked') ) { + if ( pageManagementUtils.selfContainedTemplateRadio.is(':checked') ) { $("input[name='selfContainedTemplate']").val($("input[name='customTemplate']").val()); } }, + setUsesSelfContainedTemplateInput:function() { + //On form submission attach hidden input to form if the custom template selection is picked + if ( pageManagementUtils.isSelfContainedTemplateChecked() ) { + $("").appendTo($("form")); + } + }, + //If any content is defined, keep the selContained radio button hidden checkSelfContainedRadio:function() { if ( pageManagementUtils.savedContentDivs.html().length == 0 ) { $('div#selfContainedDiv').show(); } + }, + isSelfContainedTemplateChecked:function() { + return pageManagementUtils.selfContainedTemplateRadio.is(':checked'); } } diff --git a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js index 0b7c3a827..1c803526a 100644 --- a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js +++ b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js @@ -11,7 +11,10 @@ var processFixedHTMLDataGetterContent = { processPageContentSection:function(pageContentSection) { var saveToVarValue = pageContentSection.find("input[name='saveToVar']").val(); var htmlValue = pageContentSection.find("textarea[name='htmlValue']").val(); - //query model should also be an input + //JSON parsing on the server side does not handle single quotes, as it appears it thinks the string has + //ended. Different data getter types may handle apostrophes/single quotes differently + //In this case, this is HTML so it simply html Encodes any apostrophes + htmlValue = processFixedHTMLDataGetterContent.replaceSingleQuote(htmlValue); var returnObject = {saveToVar:saveToVarValue, htmlValue:htmlValue, dataGetterClass:this.dataGetterClass}; return returnObject; }, @@ -38,13 +41,30 @@ var processFixedHTMLDataGetterContent = { //Check that query and saveToVar have been input var variableValue = pageContentSection.find("input[name='saveToVar']").val(); if(variableValue == "") { - validationError += pageContentSectionLabel + ": You must supply a variable to save HTML content.
" + validationError += pageContentSectionLabel + ": You must supply a variable to save HTML content.
"; + } + if(processFixedHTMLDataGetterContent.stringHasSingleQuote(variableValue)) { + validationError += pageContentSectionLabel + ": The variable name should not have an apostrophe .
"; + } + if(processFixedHTMLDataGetterContent.stringHasDoubleQuote(variableValue)) { + validationError += pageContentSectionLabel + ": The variable name should not have a double quote .
"; } var htmlValue = pageContentSection.find("textarea[name='htmlValue']").val(); if(htmlValue == "") { validationError += pageContentSectionLabel + ": You must supply some HTML or text.
"; } return validationError; + }, + replaceSingleQuote:function(inputStr) { + return inputStr.replace(/'/g, ''').replace(/"/g, '"'); + }, + //For the variable name, no single quote should be allowed + //This can be extended for other special characters + stringHasSingleQuote:function(inputStr) { + return(inputStr.indexOf("'") != -1); + }, + stringHasDoubleQuote:function(inputStr) { + return(inputStr.indexOf("\"") != -1); } diff --git a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl index 7bbfd170b..e2454dbe1 100644 --- a/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl +++ b/webapp/web/templates/freemarker/edit/forms/pageManagement.ftl @@ -25,7 +25,7 @@ <#assign menuItem = lvf.getFormFieldValue(editSubmission, editConfiguration, "menuItem")/> <#assign menuLinkText = lvf.getFormFieldValue(editSubmission, editConfiguration, "menuLinkText")/> <#assign customTemplate = lvf.getFormFieldValue(editSubmission, editConfiguration, "customTemplate")/> - <#assign selfContainedTemplate = lvf.getFormFieldValue(editSubmission, editConfiguration, "selfContainedTemplate")/> + <#assign selfContainedTemplate = lvf.getFormFieldValue(editSubmission, editConfiguration, "isSelfContainedTemplate")/> <#assign pageHeading = "Edit Page" /> <#if customTemplate?has_content> <#if selfContainedTemplate?has_content> @@ -67,7 +67,7 @@

${pageHeading}

-
+
style="display:none;">
checked="checked" role="input" />
-
class="hidden" role="region"> +
class="hidden" role="region"> *
@@ -140,7 +140,9 @@