diff --git a/src/main/api/studio-api.yaml b/src/main/api/studio-api.yaml index ec85208c2b..c9eb99be9f 100644 --- a/src/main/api/studio-api.yaml +++ b/src/main/api/studio-api.yaml @@ -2360,95 +2360,6 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/1/services/api/1/content/get-content-type.json: - get: - tags: - - content - summary: Get content type configuration. - description: "Required role: N/A" - operationId: getContentType - parameters: - - name: site_id - in: query - description: Project/Site ID to use - required: true - schema: - type: string - - name: type - in: query - schema: - type: string - description: Content type - required: true - example: /page/category-landing - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ContentType' - example: - name: "/page/category-landing" - label: "Category Landing" - form: "/page/category-landing" - formPath: "simple" - type: "page" - contentAsFolder: true - useRoundedFolder: false - modelInstancePath: "NOT-USED-BY-SIMPLE-FORM-ENGINE" - allowedRoles: [ ] - lastUpdated: "2023-11-10T18:00:05.882948Z" - copyDependencyPattern: [ ] - imageThumbnail: "page-category-landing.png" - noThumbnail: false - pathIncludes: [ "^/site/website/(?!articles/)(.*)" ] - pathExcludes: [ ] - nodeRef: "null" - quickCreate: false - quickCreatePath: "" - deleteDependencyPattern: [ ] - previewable: true - '400': - $ref: '#/components/responses/api1BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - - /api/1/services/api/1/content/get-content-types.json: - get: - tags: - - content - summary: Get content types allowed for given path. - description: "Required role: N/A" - operationId: getContentTypes - parameters: - - name: site - in: query - description: Project/Site ID to use - required: true - schema: - type: string - - name: path - in: query - schema: - type: string - description: Path to get content types for - required: true - example: /site/website/ - responses: - '200': - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ContentType' - '400': - $ref: '#/components/responses/api1BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - /api/1/services/api/1/content/get-item-orders.json: get: tags: @@ -3887,16 +3798,16 @@ paths: # '403': # $ref: '#/components/responses/Forbidden' - /api/2/configuration/content-type/usage: + /api/2/configuration/content_types/{siteId}/usage: get: tags: - - configuration + - contentTypes summary: Get all usage of a given content-type description: 'Required permission "content_read"' operationId: getContentTypeUsage parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -3941,16 +3852,16 @@ paths: '403': $ref: '#/components/responses/Forbidden' - /api/2/configuration/content-type/preview_image: + /api/2/configuration/content_types/{siteId}/preview_image: get: tags: - - configuration + - contentTypes summary: Get preview image of a given content type description: 'Required permission "content_read"' operationId: getContentTypePreviewImage parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -3988,69 +3899,115 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/content-type/form_controller: + /api/2/configuration/content_types/{siteId}/allowed_types: get: tags: - - configuration - summary: Get the form controller (if it exists) script of a given content type + - contentTypes + summary: Get allowed content types for a given site at a given path description: 'Required permission "content_read"' - operationId: getContentTypeFormController + operationId: getAllowedContentTypes parameters: - name: siteId - in: query + in: path description: site ID required: true schema: - type: string - - name: contentTypeId + type: string + - name: path in: query required: true schema: - type: string + type: string responses: '200': - description: 'OK' + description: OK content: - '*/*': - schema: - type: string - format: binary - description: The content of the form controller file - headers: - Content-Type: - description: The MIME type of the form controller file + application/json: schema: - type: string - Content-Length: - description: The size in bytes of the form controller file + type: object + properties: + response: + $ref: '#/components/schemas/ApiResponse' + allowedTypes: + type: array + items: + type: string + example: + - "page/article" + - "page/news" + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + + /api/2/configuration/content_types/{siteId}: + get: + tags: + - contentTypes + summary: Get content type configuration file for a given content type. It gets all content types if no contentTypeId is provided + description: 'Required permission "content_read"' + operationId: getContentTypeConfiguration + parameters: + - name: siteId + in: path + description: site ID + required: true + schema: + type: string + - name: contentTypeId + in: query + schema: + type: string + responses: + '200': + description: OK + content: + application/json: schema: - type: integer - format: int64 + type: object + properties: + response: + $ref: '#/components/schemas/ApiResponse' + contentTypes: + type: array + items: + $ref: '#/components/schemas/ContentType' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/content-type/delete: - post: + delete: tags: - - configuration + - contentTypes summary: Delete files related to a given content-type description: 'Required permission "write_configuration"' operationId: deleteContentType + parameters: + - name: siteId + in: path + description: site ID + required: true + schema: + type: string requestBody: content: application/json: schema: type: object properties: - siteId: - type: string - description: The id of the site contentType: type: string description: The content-type to delete @@ -4058,7 +4015,6 @@ paths: type: boolean description: Indicates if all dependencies of the content-type should be deleted (defaults to false) required: - - siteId - contentType responses: '200': @@ -4077,6 +4033,52 @@ paths: '403': $ref: '#/components/responses/Forbidden' + /api/2/configuration/content_types/{siteId}/form_controller: + get: + tags: + - contentTypes + summary: Get the form controller (if it exists) script of a given content type + description: 'Required permission "content_read"' + operationId: getContentTypeFormController + parameters: + - name: siteId + in: path + description: site ID + required: true + schema: + type: string + - name: contentTypeId + in: query + required: true + schema: + type: string + responses: + '200': + description: 'OK' + content: + '*/*': + schema: + type: string + format: binary + description: The content of the form controller file + headers: + Content-Type: + description: The MIME type of the form controller file + schema: + type: string + Content-Length: + description: The size in bytes of the form controller file + schema: + type: integer + format: int64 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' /api/2/plugin/file: # Override the server to change the prefix @@ -8260,6 +8262,7 @@ components: * `CODE:` 52004, `MESSAGE:` S3 FORBIDDEN, `REMEDIAL ACTION:` Check your AWS credentials * `CODE:` 52005, `MESSAGE:` S3 key not found, `REMEDIAL ACTION:` Check your network configuration and S3 availability * `CODE:` 53000, `MESSAGE:` Logger not found, `REMEDIAL ACTION:` Check if you sent in the right logger name or add 'createIfAbsent=true' parameter to create the logger if it does not exist + * `CODE:` 54000, `MESSAGE:` The content type cannot be deleted because it is still in use by content items, `REMEDIAL ACTION:` Check if you sent in the right content type id or add 'deleteDependencies' to force delete properties: code: type: integer @@ -10515,77 +10518,79 @@ components: ContentType: type: object + description: Represents a content type in the system. properties: - name: + id: type: string - description: The site content name + description: Unique identifier for the content type. label: type: string - description: The content type display name - form: - type: string - description: The content type form - formPath: - type: string - description: The content type form path + description: Human-readable label for the content type. type: type: string - description: The type, e.g. page, component, etc - contentAsFolder: - type: boolean - description: "Indicates whether to create content in a folder wrapper e.g. pageUrl: 101 means 101\\/index.xml instead of 101.xml" - useRoundedFolder: - type: boolean - description: Indicates whether use rounded folder to arrange content - modelInstancePath: - type: string - description: The path to the model instance file (WCM) + description: The type of content. + enum: [PAGE, COMPONENT, UNKNOWN] allowedRoles: type: array + description: Set of roles allowed to access this content type. items: - type: string - description: The list of roles allowed - lastUpdated: - type: string - description: The date the content type was last updated - copyDependencyPattern: + type: object + description: Role allowed to access the content type. + properties: + name: + type: string + description: Name of the role. + deleteDependencies: type: array + description: List of dependencies to delete with this content type. items: - type: string - description: The list of copy association patterns + type: object + description: Dependency to delete with the content type. + properties: + pattern: + type: string + description: Pattern for the dependency to delete. + removeEmptyFolder: + type: boolean + description: Whether to remove the folder if it becomes empty after deletion. + copyDependencies: + type: array + description: List of dependencies to copy with this content type. + items: + type: object + description: Dependency to copy with the content type. + properties: + pattern: + type: string + description: Pattern for the dependency to copy. + target: + type: string + description: Target path for the copied dependency. + previewable: + type: boolean + description: Whether the content type is previewable. imageThumbnail: type: string - description: The thumbnail image file to be displayed + description: Path or URL to the thumbnail image. noThumbnail: type: boolean - description: Indicates whether content type has a thumbnail + description: Whether the content type has no thumbnail. pathIncludes: type: array items: type: string - description: The the list of included paths + description: List of path patterns to include. pathExcludes: type: array items: type: string - description: The the list of excluded paths - nodeRef: - type: string - description: The configuration noderef this content type is associated with + description: List of path patterns to exclude. quickCreate: type: boolean - description: Indicates whether the content type is available from the quick create button + description: Whether quick create is enabled for this content type. quickCreatePath: type: string - description: The destination path pattern of content type - deleteDependencyPattern: - type: array - items: - type: string - description: The list of delete association patterns that this content type is dependent on for deleting indexes in webproject - previewable: - type: boolean - description: Indicates whether the content type is previewable + description: Path to use for quick create. ContentItemV1: type: object diff --git a/src/main/java/org/craftercms/studio/api/v2/exception/contentType/ContentTypeUsageException.java b/src/main/java/org/craftercms/studio/api/v2/exception/contentType/ContentTypeUsageException.java new file mode 100644 index 0000000000..e572c73a48 --- /dev/null +++ b/src/main/java/org/craftercms/studio/api/v2/exception/contentType/ContentTypeUsageException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.api.v2.exception.contentType; + +import org.craftercms.studio.api.v1.exception.ServiceLayerException; + +/** + * Exception to be thrown when trying to delete a content type that is still in use by content items + */ +public class ContentTypeUsageException extends ServiceLayerException { + + public ContentTypeUsageException(String siteId, String contentType) { + super(String.format("Content type '%s' is still in use by content items in site '%s'", contentType, siteId)); + } +} diff --git a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java index 1edfee9494..c3b3741625 100644 --- a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java +++ b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,9 +17,11 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.craftercms.studio.api.v1.exception.ServiceLayerException; +import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v2.dal.QuickCreateItem; +import org.craftercms.studio.model.contentType.ContentType; import org.craftercms.studio.model.contentType.ContentTypeUsage; import org.springframework.core.io.Resource; @@ -109,4 +111,30 @@ void deleteContentType(String siteId, String contentType, boolean deleteDependen * @return List of quick creatable content types */ List getQuickCreatableContentTypes(String siteId) throws ServiceLayerException; + + /** + * Get all content types for the given site. + * @param siteId the id of the site + * @return a collection of content types + * @throws SiteNotFoundException if the site with the given id does not exist + */ + Collection getAllContentTypes(String siteId) throws ServiceLayerException; + + /** + * Get the content type configuration for a given content type id + * + * @param siteId the id of the site + * @param contentTypeId the id of the content type + * @return the content type configuration + */ + ContentType getContentType(String siteId, String contentTypeId) throws ServiceLayerException; + + /** + * Get a collection of the ids of the content types allowed for the given site and path + * + * @param siteId the id of the site + * @param path the path of the content item to be created + * @return a collection of the ids of the content types allowed for the given site and path + */ + Collection getAllowedContentTypes(String siteId, String path) throws ServiceLayerException; } diff --git a/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java b/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java index d78171b682..fdb6398af7 100644 --- a/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java +++ b/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -21,6 +21,7 @@ import org.apache.commons.io.IOUtils; import org.craftercms.commons.http.RequestContext; import org.craftercms.studio.api.v1.constant.StudioConstants; +import org.craftercms.studio.model.contentType.ContentType; import org.dom4j.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +36,7 @@ import java.nio.file.Paths; import java.util.List; import java.util.UUID; +import java.util.regex.Pattern; import static org.apache.commons.io.FilenameUtils.directoryContains; import static org.apache.commons.lang3.StringUtils.isEmpty; @@ -116,6 +118,7 @@ public static Path getStudioTemporaryFilesRoot() { * @throws IOException if an error occurs while creating the file */ public static Path createTempFile(String name) throws IOException { + Files.createDirectories(getStudioTemporaryFilesRoot()); return Files.createTempFile(getStudioTemporaryFilesRoot(), UUID.randomUUID().toString(), "." + FilenameUtils.getExtension(name)); } @@ -240,4 +243,24 @@ public static boolean underPagesRoot(String path) { public static String movePath(String sourceRoot, String targetRoot, String sourcePath) { return Path.of(targetRoot).resolve(Path.of(sourceRoot).relativize(Path.of(sourcePath))).toString(); } + + /** + * Get the content type type by its id, which is determined by the content type naming convention. + * + * @param contentTypeId the content type id to check + * @return
    + *
  • component if the name matches component naming convention
  • + *
  • page if the name matches page naming convention
  • + *
  • unknown if name don't match any known convention
  • + *
+ */ + public static ContentType.Type getContentTypeTypeById(String contentTypeId) { + if (Pattern.matches("/component/.*?", contentTypeId)) { + return ContentType.Type.component; + } + if (Pattern.matches("/page/.*?", contentTypeId)){ + return ContentType.Type.page; + } + return ContentType.Type.unknown; + } } diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java b/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java index c443de8dcb..9ce2d8d892 100644 --- a/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,10 +16,7 @@ package org.craftercms.studio.controller.rest.v2; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import jakarta.validation.Valid; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; import org.craftercms.commons.validation.annotations.param.EsapiValidatedParam; import org.craftercms.commons.validation.annotations.param.ValidConfigurationPath; import org.craftercms.commons.validation.annotations.param.ValidSiteId; @@ -28,9 +25,7 @@ import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v2.annotation.LogExecutionTime; import org.craftercms.studio.api.v2.service.config.ConfigurationService; -import org.craftercms.studio.api.v2.service.content.ContentTypeService; import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.api.v2.utils.StudioUtils; import org.craftercms.studio.model.config.TranslationConfiguration; import org.craftercms.studio.model.rest.ConfigurationHistory; import org.craftercms.studio.model.rest.Result; @@ -38,9 +33,6 @@ import org.craftercms.studio.model.rest.WriteConfigurationRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -51,30 +43,28 @@ import static org.apache.commons.lang3.Strings.CS; import static org.craftercms.commons.validation.annotations.param.EsapiValidationType.ALPHANUMERIC; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_GLOBAL_SYSTEM_SITE; -import static org.craftercms.studio.controller.rest.v2.ResultConstants.*; -import static org.craftercms.studio.model.rest.ApiResponse.DELETED; +import static org.craftercms.studio.controller.rest.v2.RequestMappingConstants.*; +import static org.craftercms.studio.controller.rest.v2.ResultConstants.RESULT_KEY_CONFIG; +import static org.craftercms.studio.controller.rest.v2.ResultConstants.RESULT_KEY_HISTORY; import static org.craftercms.studio.model.rest.ApiResponse.OK; @Validated @RestController -@RequestMapping("/api/2/configuration") +@RequestMapping(API_2 + CONFIGURATION) public class ConfigurationController { private final ConfigurationService configurationService; private final StudioConfiguration studioConfiguration; - private final ContentTypeService contentTypeService; @SuppressWarnings("unused") private static final Logger logger = LoggerFactory.getLogger(ConfigurationController.class); - @ConstructorProperties({"configurationService", "studioConfiguration", "contentTypeService"}) - public ConfigurationController(ConfigurationService configurationService, StudioConfiguration studioConfiguration, - ContentTypeService contentTypeService) { + @ConstructorProperties({"configurationService", "studioConfiguration"}) + public ConfigurationController(ConfigurationService configurationService, StudioConfiguration studioConfiguration) { this.configurationService = configurationService; this.studioConfiguration = studioConfiguration; - this.contentTypeService = contentTypeService; } - @GetMapping("clear_cache") + @GetMapping(CLEAR_CACHE) public Result clearCache(@ValidSiteId @RequestParam String siteId) { configurationService.invalidateConfiguration(siteId); var result = new Result(); @@ -82,7 +72,7 @@ public Result clearCache(@ValidSiteId @RequestParam String siteId) { return result; } - @GetMapping("/get_configuration") + @GetMapping(GET_CONFIGURATION) @LogExecutionTime public ResultOne getConfiguration(@ValidSiteId @RequestParam(name = "siteId", required = true) String siteId, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "module", required = true) String module, @@ -102,7 +92,7 @@ public ResultOne getConfiguration(@ValidSiteId @RequestParam(name = "sit return result; } - @PostMapping("/write_configuration") + @PostMapping(WRITE_CONFIGURATION) public Result writeConfiguration(@Validated @RequestBody WriteConfigurationRequest wcRequest) throws ServiceLayerException, UserNotFoundException, AuthenticationException { InputStream is = IOUtils.toInputStream(wcRequest.getContent(), UTF_8); @@ -118,7 +108,7 @@ public Result writeConfiguration(@Validated @RequestBody WriteConfigurationReque return result; } - @GetMapping("/get_configuration_history") + @GetMapping(GET_CONFIGURATION_HISTORY) public ResultOne getConfigurationHistory(@ValidSiteId @RequestParam(name = "siteId", required = true) String siteId, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "module", required = true) String module, @ValidConfigurationPath @RequestParam(name = "path", required = true) String path, @@ -132,7 +122,7 @@ public ResultOne getConfigurationHistory(@ValidSiteId @Req return result; } - @GetMapping("translation") + @GetMapping(TRANSLATION) public ResultOne getTranslationConfiguration(@ValidSiteId @RequestParam String siteId) throws ServiceLayerException { ResultOne result = new ResultOne<>(); result.setEntity(RESULT_KEY_CONFIG, configurationService.getTranslationConfiguration(siteId)); @@ -140,87 +130,4 @@ public ResultOne getTranslationConfiguration(@ValidSit return result; } - @GetMapping("content-type/usage") - public ResultOne getContentTypeUsage(@ValidSiteId @RequestParam String siteId, - @ValidConfigurationPath @RequestParam String contentType) - throws Exception { - var result = new ResultOne<>(); - result.setResponse(OK); - result.setEntity(RESULT_KEY_USAGE, contentTypeService.getContentTypeUsage(siteId, contentType)); - - return result; - } - - @GetMapping("content-type/form_controller") - public ResponseEntity getContentTypeFormController(@ValidSiteId @RequestParam String siteId, - @ValidConfigurationPath @RequestParam String contentTypeId) throws ServiceLayerException { - ImmutablePair resource = contentTypeService.getContentTypeFormController(siteId, contentTypeId); - return getResourceResponse(resource.getKey(), resource.getValue()); - } - - @GetMapping("content-type/preview_image") - public ResponseEntity getContentTypePreviewImage(@ValidSiteId @RequestParam String siteId, - @ValidConfigurationPath @RequestParam String contentTypeId) - throws ServiceLayerException { - ImmutablePair resource = contentTypeService.getContentTypePreviewImage(siteId, contentTypeId); - return getResourceResponse(resource.getKey(), resource.getValue()); - } - - private ResponseEntity getResourceResponse(String name, Resource resource) { - String mimeType = StudioUtils.getMimeType(name); - - return ResponseEntity - .ok() - .header(HttpHeaders.CONTENT_TYPE, mimeType) - .body(resource); - } - - @PostMapping("content-type/delete") - public Result deleteContentType(@RequestBody @Valid DeleteContentTypeRequest request) - throws ServiceLayerException, AuthenticationException, UserNotFoundException { - contentTypeService.deleteContentType(request.getSiteId(), request.getContentType(), - request.isDeleteDependencies()); - var result = new Result(); - result.setResponse(DELETED); - - return result; - } - - @JsonIgnoreProperties - public static class DeleteContentTypeRequest { - - @ValidSiteId - protected String siteId; - - @ValidConfigurationPath - protected String contentType; - - protected boolean deleteDependencies; - - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public boolean isDeleteDependencies() { - return deleteDependencies; - } - - public void setDeleteDependencies(boolean deleteDependencies) { - this.deleteDependencies = deleteDependencies; - } - - } - } diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/ContentTypeController.java b/src/main/java/org/craftercms/studio/controller/rest/v2/ContentTypeController.java new file mode 100644 index 0000000000..6891bcff47 --- /dev/null +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/ContentTypeController.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.controller.rest.v2; + +import jakarta.validation.Valid; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.craftercms.commons.validation.annotations.param.ValidConfigurationPath; +import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; +import org.craftercms.commons.validation.annotations.param.ValidSiteId; +import org.craftercms.commons.validation.annotations.param.ValidateSecurePathParam; +import org.craftercms.studio.api.v1.exception.ServiceLayerException; +import org.craftercms.studio.api.v1.exception.security.AuthenticationException; +import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; +import org.craftercms.studio.api.v2.service.content.ContentTypeService; +import org.craftercms.studio.api.v2.utils.StudioUtils; +import org.craftercms.studio.model.contentType.ContentType; +import org.craftercms.studio.model.rest.Result; +import org.craftercms.studio.model.rest.ResultList; +import org.craftercms.studio.model.rest.ResultOne; +import org.craftercms.studio.model.rest.contentType.DeleteContentTypeRequest; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.beans.ConstructorProperties; +import java.util.Collection; +import java.util.List; + +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.craftercms.studio.controller.rest.v2.RequestMappingConstants.*; +import static org.craftercms.studio.controller.rest.v2.ResultConstants.*; +import static org.craftercms.studio.model.rest.ApiResponse.DELETED; +import static org.craftercms.studio.model.rest.ApiResponse.OK; + +@Validated +@RestController +@RequestMapping(API_2 + CONFIGURATION + CONTENT_TYPES + SITE_ID) +public class ContentTypeController { + private final ContentTypeService contentTypeService; + + @ConstructorProperties("contentTypeService") + public ContentTypeController(ContentTypeService contentTypeService) { + this.contentTypeService = contentTypeService; + } + + @GetMapping(USAGE) + public ResultOne getContentTypeUsage(@ValidSiteId @PathVariable String siteId, + @ValidConfigurationPath @RequestParam String contentType) + throws Exception { + var result = new ResultOne<>(); + result.setResponse(OK); + result.setEntity(RESULT_KEY_USAGE, contentTypeService.getContentTypeUsage(siteId, contentType)); + + return result; + } + + @GetMapping(FORM_CONTROLLER) + public ResponseEntity getContentTypeFormController(@ValidSiteId @PathVariable String siteId, + @ValidConfigurationPath @RequestParam String contentTypeId) throws ServiceLayerException { + ImmutablePair resource = contentTypeService.getContentTypeFormController(siteId, contentTypeId); + return getResourceResponse(resource.getKey(), resource.getValue()); + } + + @GetMapping(PREVIEW_IMAGE) + public ResponseEntity getContentTypePreviewImage(@ValidSiteId @PathVariable String siteId, + @ValidConfigurationPath @ValidateSecurePathParam @RequestParam String contentTypeId) + throws ServiceLayerException { + ImmutablePair resource = contentTypeService.getContentTypePreviewImage(siteId, contentTypeId); + return getResourceResponse(resource.getKey(), resource.getValue()); + } + + @GetMapping + public ResultList getContentTypes(@ValidSiteId @PathVariable String siteId, + @ValidConfigurationPath @RequestParam(required = false) String contentTypeId) throws ServiceLayerException { + var result = new ResultList(); + result.setResponse(OK); + + Collection contentTypes; + if (isEmpty(contentTypeId)) { + contentTypes = contentTypeService.getAllContentTypes(siteId); + } else { + contentTypes = List.of(contentTypeService.getContentType(siteId, contentTypeId)); + } + result.setEntities(RESULT_KEY_CONTENT_TYPES, contentTypes); + return result; + } + + @GetMapping(ALLOWED_TYPES) + public ResultList getAllowedContentTypes(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam String path) throws ServiceLayerException { + ResultList result = new ResultList<>(); + result.setResponse(OK); + result.setEntities(RESULT_KEY_ALLOWED_TYPES, contentTypeService.getAllowedContentTypes(siteId, path)); + return result; + } + + @DeleteMapping + public Result deleteContentType(@ValidSiteId @PathVariable String siteId, @RequestBody @Valid DeleteContentTypeRequest request) + throws ServiceLayerException, AuthenticationException, UserNotFoundException { + contentTypeService.deleteContentType(siteId, request.getContentType(), + request.isDeleteDependencies()); + var result = new Result(); + result.setResponse(DELETED); + return result; + } + + private ResponseEntity getResourceResponse(String name, Resource resource) { + String mimeType = StudioUtils.getMimeType(name); + + return ResponseEntity + .ok() + .header(HttpHeaders.CONTENT_TYPE, mimeType) + .body(resource); + } +} diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java b/src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java index 9c079d3f41..9e83e1fb15 100644 --- a/src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java @@ -41,6 +41,7 @@ import org.craftercms.studio.api.v2.exception.content.ContentInPublishQueueException; import org.craftercms.studio.api.v2.exception.content.ContentLockedByAnotherUserException; import org.craftercms.studio.api.v2.exception.content.ContentMoveInvalidLocation; +import org.craftercms.studio.api.v2.exception.contentType.ContentTypeUsageException; import org.craftercms.studio.api.v2.exception.git.MergeInProgressException; import org.craftercms.studio.api.v2.exception.git.NoMergeStateException; import org.craftercms.studio.api.v2.exception.logger.LoggerNotFoundException; @@ -681,6 +682,14 @@ public Result handleException(HttpServletRequest request, NoMergeStateException return handleExceptionInternal(request, e, response); } + @ExceptionHandler + @ResponseStatus(CONFLICT) + public Result handleException(HttpServletRequest request, ContentTypeUsageException e) { + ApiResponse response = new ApiResponse(ApiResponse.CONTENT_TYPE_IN_USE); + response.setMessage(e.getMessage()); + return handleExceptionInternal(request, e, response); + } + @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Result handleException(HttpServletRequest request, Exception e) { diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java b/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java index 7d9c34d073..960d081ece 100644 --- a/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java @@ -164,6 +164,20 @@ public final class RequestMappingConstants { */ public static final String MONITOR = "/monitor"; + /** + * Configuration Controller + */ + public static final String CONFIGURATION = "/configuration"; + public static final String CLEAR_CACHE = "/clear_cache"; + public static final String GET_CONFIGURATION = "/get_configuration"; + public static final String WRITE_CONFIGURATION = "/write_configuration"; + public static final String GET_CONFIGURATION_HISTORY = "/get_configuration_history"; + public static final String TRANSLATION = "/translation"; + public static final String CONTENT_TYPES = "/content_types"; + public static final String USAGE = "/usage"; + public static final String PREVIEW_IMAGE = "/preview_image"; + public static final String FORM_CONTROLLER = "/form_controller"; + public static final String ALLOWED_TYPES = "/allowed_types"; private RequestMappingConstants() { } diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/ResultConstants.java b/src/main/java/org/craftercms/studio/controller/rest/v2/ResultConstants.java index 2040faafa4..8f106760c9 100644 --- a/src/main/java/org/craftercms/studio/controller/rest/v2/ResultConstants.java +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/ResultConstants.java @@ -117,6 +117,12 @@ public final class ResultConstants { */ public static final String RESULT_KEY_MONITORS = "monitors"; + /** + * Content types controller + */ + public static final String RESULT_KEY_CONTENT_TYPES = "contentTypes"; + public static final String RESULT_KEY_ALLOWED_TYPES = "allowedTypes"; + /** * Exception Handler */ diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java index 0c9756b345..b17903aac1 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -33,6 +33,7 @@ import org.craftercms.studio.api.v2.dal.security.NormalizedRole; import org.craftercms.studio.api.v2.service.config.ConfigurationService; import org.craftercms.studio.api.v2.utils.StudioConfiguration; +import org.craftercms.studio.api.v2.utils.StudioUtils; import org.craftercms.studio.impl.v1.util.ContentFormatUtils; import org.craftercms.studio.impl.v2.utils.DateUtils; import org.dom4j.Document; @@ -51,6 +52,7 @@ import static org.craftercms.studio.api.v1.constant.StudioConstants.FILE_SEPARATOR; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_PATH; +import static org.craftercms.studio.api.v2.utils.StudioUtils.getContentTypeTypeById; /** * @author Dejan Brkic @@ -127,7 +129,7 @@ public ContentTypeConfigTO loadConfiguration(@ValidateStringParam String site, loadDeleteDependencies(contentTypeConfig, root.selectNodes("delete-dependencies/delete-dependency")); loadCopyDependencyPatterns(contentTypeConfig, root.selectNodes("copy-dependencies/copy-dependency")); contentTypeConfig.setLastUpdated(DateUtils.getCurrentTime()); - contentTypeConfig.setType(getContentTypeTypeByName(name)); + contentTypeConfig.setType(getContentTypeTypeById(name).name()); boolean quickCreate = ContentFormatUtils.getBooleanValue(root.valueOf(QUICK_CREATE)); contentTypeConfig.setQuickCreate(quickCreate); contentTypeConfig.setQuickCreatePath(root.valueOf(QUICK_CREATE_PATH)); @@ -172,26 +174,6 @@ protected void loadDeleteDependencies(ContentTypeConfigTO contentTypeConfig, Lis } } - /** - * Checks name for naming convention. - * - * @param name Name to be check - * @return
    - *
  • component if the name matches component naming convention
  • - *
  • page if the name matches page naming convention
  • - *
  • unknown if name don't match any known convention
  • - *
- */ - private String getContentTypeTypeByName(String name) { - if (Pattern.matches("/component/.*?", name)) { - return "component"; - } else if (Pattern.matches("/page/.*?", name)) - return "page"; - else { - return "unknown"; - } - } - /** * get paths * diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentTypeServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentTypeServiceImpl.java index 108c015ece..f0bd472fb3 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentTypeServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentTypeServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -21,10 +21,12 @@ import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; +import org.craftercms.studio.api.v2.annotation.ContentPath; import org.craftercms.studio.api.v2.annotation.RequireSiteReady; import org.craftercms.studio.api.v2.annotation.SiteId; import org.craftercms.studio.api.v2.dal.QuickCreateItem; import org.craftercms.studio.api.v2.service.content.ContentTypeService; +import org.craftercms.studio.model.contentType.ContentType; import org.craftercms.studio.model.contentType.ContentTypeUsage; import org.springframework.core.io.Resource; @@ -116,6 +118,27 @@ public List getQuickCreatableContentTypes(@SiteId String siteId return contentTypeServiceInternal.getQuickCreatableContentTypes(siteId); } + @Override + @RequireSiteReady + @HasPermission(type = DefaultPermission.class, action = PERMISSION_CONTENT_READ) + public Collection getAllContentTypes(@SiteId String siteId) throws ServiceLayerException { + return contentTypeServiceInternal.getAllContentTypes(siteId); + } + + @Override + @RequireSiteReady + @HasPermission(type = DefaultPermission.class, action = PERMISSION_CONTENT_READ) + public ContentType getContentType(@SiteId String siteId, String contentTypeId) throws ServiceLayerException { + return contentTypeServiceInternal.getContentType(siteId, contentTypeId); + } + + @Override + @RequireSiteReady + @HasPermission(type = DefaultPermission.class, action = PERMISSION_CONTENT_READ) + public Collection getAllowedContentTypes(@SiteId String siteId, @ContentPath String path) throws ServiceLayerException { + return contentTypeServiceInternal.getAllowedContentTypes(siteId, path); + } + @Override @HasPermission(type = DefaultPermission.class, action = PERMISSION_READ_CONFIGURATION) public String getContentTypeControllerPath(String contentTypeId) { diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java index 3490cb9cce..0096aafad8 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java @@ -94,7 +94,6 @@ import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.Node; -import org.eclipse.jgit.api.errors.GitAPIException; import org.jspecify.annotations.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java index bbfb95e46e..b8c3fd95ec 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,29 +16,32 @@ package org.craftercms.studio.impl.v2.service.content.internal; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.google.common.cache.Cache; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.craftercms.commons.lang.UrlUtils; -import org.craftercms.commons.validation.annotations.param.ValidateSecurePathParam; import org.craftercms.studio.api.v1.exception.ContentNotFoundException; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; -import org.craftercms.studio.api.v1.service.content.ContentTypeService; import org.craftercms.studio.api.v1.service.security.SecurityService; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; import org.craftercms.studio.api.v2.annotation.RequireSiteExists; import org.craftercms.studio.api.v2.annotation.SiteId; import org.craftercms.studio.api.v2.dal.ItemDAO; import org.craftercms.studio.api.v2.dal.QuickCreateItem; import org.craftercms.studio.api.v2.dal.item.LightItem; +import org.craftercms.studio.api.v2.exception.configuration.ConfigurationException; +import org.craftercms.studio.api.v2.exception.contentType.ContentTypeUsageException; import org.craftercms.studio.api.v2.service.config.ConfigurationService; import org.craftercms.studio.api.v2.service.content.ContentService; import org.craftercms.studio.api.v2.service.publish.PublishService; import org.craftercms.studio.api.v2.utils.GitRepositoryHelper; +import org.craftercms.studio.impl.v2.utils.Wrapper; import org.craftercms.studio.impl.v2.utils.security.SecurityUtils; +import org.craftercms.studio.model.contentType.ContentType; import org.craftercms.studio.model.contentType.ContentTypeUsage; import org.dom4j.Document; import org.dom4j.Node; @@ -51,32 +54,34 @@ import java.beans.ConstructorProperties; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import static java.lang.String.format; import static java.nio.file.Files.walkFileTree; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; +import static org.apache.commons.collections4.CollectionUtils.isEmpty; import static org.apache.commons.io.FilenameUtils.normalize; import static org.apache.commons.lang3.RegExUtils.replaceAll; -import static org.apache.commons.lang3.StringUtils.*; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.apache.commons.lang3.Strings.CI; import static org.craftercms.studio.api.v1.constant.GitRepositories.SANDBOX; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; import static org.craftercms.studio.permissions.StudioPermissionsConstants.PERMISSION_CONTENT_CREATE; +/** + * Internal implementation of {@link org.craftercms.studio.api.v2.service.content.ContentTypeService}. + */ public class ContentTypeServiceInternalImpl implements org.craftercms.studio.api.v2.service.content.ContentTypeService { private static final Logger logger = LoggerFactory.getLogger(ContentTypeServiceInternalImpl.class); - protected final ContentTypeService contentTypeService; protected final SecurityService securityService; protected final ConfigurationService configurationService; protected final ItemDAO itemDao; @@ -85,7 +90,6 @@ public class ContentTypeServiceInternalImpl implements org.craftercms.studio.api protected final String contentTypeBasePathPattern; protected final String contentTypesRootPath; protected final String contentTypeDefinitionFilename; - protected final String contentTypeConfigFilename; protected final String templateXPath; protected final String controllerPattern; protected final String controllerFormat; @@ -93,27 +97,28 @@ public class ContentTypeServiceInternalImpl implements org.craftercms.studio.api protected final String defaultPreviewImagePath; protected final String formControllerFilePath; private final GitRepositoryHelper gitRepositoryHelper; - - @ConstructorProperties({"contentTypeService", "securityService", "configurationService", "itemDao", - "contentTypeBasePathPattern", "contentTypeDefinitionFilename", "contentTypeConfigFilename", - "contentTypesRootPath", - "templateXPath", "controllerPattern", "controllerFormat", "previewImageXPath", "defaultPreviewImagePath", - "formControllerFilePath", "gitRepositoryHelper"}) - public ContentTypeServiceInternalImpl(ContentTypeService contentTypeService, SecurityService securityService, + private final Cache cache; + private final XmlMapper xmlMapper; + + @ConstructorProperties({"securityService", "configurationService", "itemDao", + "contentTypeBasePathPattern", "contentTypeDefinitionFilename", + "contentTypesRootPath", + "templateXPath", "controllerPattern", "controllerFormat", "previewImageXPath", "defaultPreviewImagePath", + "formControllerFilePath", "gitRepositoryHelper", + "cache"}) + public ContentTypeServiceInternalImpl(SecurityService securityService, ConfigurationService configurationService, ItemDAO itemDao, String contentTypeBasePathPattern, - String contentTypeDefinitionFilename, String contentTypeConfigFilename, + String contentTypeDefinitionFilename, String contentTypesRootPath, String templateXPath, String controllerPattern, String controllerFormat, String previewImageXPath, String defaultPreviewImagePath, - String formControllerFilePath, - GitRepositoryHelper gitRepositoryHelper) { - this.contentTypeService = contentTypeService; + String formControllerFilePath, GitRepositoryHelper gitRepositoryHelper, + Cache cache) { this.securityService = securityService; this.configurationService = configurationService; this.itemDao = itemDao; this.contentTypeBasePathPattern = contentTypeBasePathPattern; this.contentTypeDefinitionFilename = contentTypeDefinitionFilename; - this.contentTypeConfigFilename = contentTypeConfigFilename; this.contentTypesRootPath = contentTypesRootPath; this.templateXPath = templateXPath; this.controllerPattern = controllerPattern; @@ -122,6 +127,8 @@ public ContentTypeServiceInternalImpl(ContentTypeService contentTypeService, Sec this.defaultPreviewImagePath = defaultPreviewImagePath; this.formControllerFilePath = formControllerFilePath; this.gitRepositoryHelper = gitRepositoryHelper; + this.cache = cache; + this.xmlMapper = new XmlMapper(); } public void setContentService(ContentService contentService) { @@ -130,26 +137,109 @@ public void setContentService(ContentService contentService) { @Override public List getQuickCreatableContentTypes(String siteId) throws ServiceLayerException { - return contentTypeService.getAllContentTypes(siteId, true).stream() - .filter(ContentTypeConfigTO::isQuickCreate) - .filter(contentType -> { - try { - return securityService.getUserPermissions(siteId, contentType.getQuickCreatePath(), SecurityUtils.getCurrentUsername()) - .contains(PERMISSION_CONTENT_CREATE); - } catch (SiteNotFoundException e) { - // This should never happen. If the site does not exist then getAllContentTypes() call above should have thrown an exception - return false; + return getAllContentTypes(siteId).stream() + .filter(ContentType::isQuickCreate) + .filter(contentType -> { + try { + return securityService.getUserPermissions(siteId, contentType.getQuickCreatePath(), SecurityUtils.getCurrentUsername()) + .contains(PERMISSION_CONTENT_CREATE); + } catch (SiteNotFoundException e) { + // This should never happen. If the site does not exist then getAllContentTypes() call above should have thrown an exception + return false; + } + }) + .map(contentType -> { + QuickCreateItem item = new QuickCreateItem(); + item.setSiteId(siteId); + item.setContentTypeId(contentType.getId()); + item.setLabel(contentType.getLabel()); + item.setPath(contentType.getQuickCreatePath()); + return item; + }) + .collect(toList()); + } + + @Override + public Collection getAllContentTypes(String siteId) throws ServiceLayerException { + Collection contentTypes = new ArrayList<>(); + + Path repoRootPath = gitRepositoryHelper.buildRepoPath(SANDBOX, siteId); + Path contentTypesRepoPath = repoRootPath.resolve(gitRepositoryHelper.getGitPath(contentTypesRootPath)); + try { + Wrapper fileVisitorException = new Wrapper<>(); + walkFileTree(contentTypesRepoPath, new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + if (!file.getFileName().toString().equals(contentTypeDefinitionFilename)) { + return FileVisitResult.CONTINUE; + } + try { + contentTypes.add(getContentType(siteId, contentTypesRepoPath.relativize(file.getParent()).toString())); + } catch (ServiceLayerException e) { + fileVisitorException.set(e); + return FileVisitResult.TERMINATE; + } + return FileVisitResult.SKIP_SIBLINGS; } - }) - .map(contentType -> { - QuickCreateItem item = new QuickCreateItem(); - item.setSiteId(siteId); - item.setContentTypeId(contentType.getForm()); - item.setLabel(contentType.getLabel()); - item.setPath(contentType.getQuickCreatePath()); - return item; - }) - .collect(toList()); + }); + if (fileVisitorException.hasValue()) { + throw fileVisitorException.get(); + } + } catch (Exception e) { + throw new ServiceLayerException(format("Failed to retrieve content types for site '%s'", siteId), e); + } + + return contentTypes; + } + + @Override + public ContentType getContentType(String siteId, String contentTypeId) throws ServiceLayerException { + String configFileFullPath = getContentTypeFormPath(contentTypeId); + var cacheKey = configurationService.getCacheKey(siteId, null, configFileFullPath, + null, "object"); + ContentType contentType = cache.getIfPresent(cacheKey); + if (contentType == null) { + logger.debug("Cache miss for key '{}'", cacheKey); + contentType = loadContentType(siteId, contentTypeId); + cache.put(cacheKey, contentType); + } + + return contentType; + } + + /** + * Get content type form-definition.xml full path in content repository + */ + private String getContentTypeFormPath(String contentTypeId) { + String siteConfigPath = getContentTypePath(contentTypeId); + String configFileFullPath = siteConfigPath + FILE_SEPARATOR + contentTypeDefinitionFilename; + return configFileFullPath; + } + + /** + * Load content type form-definition.xml from content repository and map it to ContentType object + * + * @param siteId the site id + * @param contentTypeId the content type id + * @return the ContentType object mapped from form-definition.xml + * @throws ConfigurationException if there is any error reading the content type configuration + */ + protected ContentType loadContentType(String siteId, String contentTypeId) throws ConfigurationException, ContentNotFoundException { + InputStream configurationAsStream = contentService.getContent(siteId, getContentTypeFormPath(contentTypeId)); + try { + return xmlMapper.readValue(configurationAsStream, ContentType.class); + } catch (IOException e) { + throw new ConfigurationException(format("Failed to read content type configuration for content type '%s' in site '%s'", contentTypeId, siteId), e); + } + } + + @Override + public Collection getAllowedContentTypes(String siteId, String path) throws ServiceLayerException { + return getAllContentTypes(siteId).stream() + .filter(ct -> isEmpty(ct.getPathIncludes()) || ct.getPathIncludes().stream().anyMatch(path::matches)) + .filter(ct -> ct.getPathExcludes().stream().noneMatch(path::matches)) + .map(ContentType::getId) + .collect(toList()); } @Override @@ -167,21 +257,21 @@ public ContentTypeUsage getContentTypeUsage(String siteId, String contentType) t List items = itemDao.getContentTypeUsages(siteId, contentType, scriptPath); usages.setContent(items.stream() - .filter(i -> equalsAnyIgnoreCase(i.getMetadata().systemType(), CONTENT_TYPE_PAGE, CONTENT_TYPE_COMPONENT)) - .map(LightItem::getPath) - .collect(toList())); + .filter(i -> CI.equalsAny(i.getMetadata().systemType(), CONTENT_TYPE_PAGE, CONTENT_TYPE_COMPONENT)) + .map(LightItem::getPath) + .collect(toList())); usages.setScripts(items.stream() - .filter(i -> equalsIgnoreCase(i.getMetadata().systemType(), (CONTENT_TYPE_SCRIPT))) - .map(LightItem::getPath) - .collect(toList())); + .filter(i -> CI.equals(i.getMetadata().systemType(), (CONTENT_TYPE_SCRIPT))) + .map(LightItem::getPath) + .collect(toList())); return usages; } @Override public ImmutablePair getContentTypePreviewImage(String siteId, - @ValidateSecurePathParam String contentTypeId) throws ServiceLayerException { + String contentTypeId) throws ServiceLayerException { String filename = getContentTypePreviewImageFilename(siteId, contentTypeId); boolean hasPreviewImage = isNotEmpty(filename) && !filename.equals("undefined"); // form-definition could have undefined value for imageThumbnail @@ -205,15 +295,14 @@ public ImmutablePair getContentTypeFormController(String siteI @Override public void deleteContentType(String siteId, String contentType, boolean deleteDependencies) - throws ServiceLayerException, AuthenticationException, UserNotFoundException { + throws ServiceLayerException, AuthenticationException, UserNotFoundException { ContentTypeUsage usage = getContentTypeUsage(siteId, contentType); var files = new HashSet(); if (CollectionUtils.isNotEmpty(usage.getContent())) { if (!deleteDependencies) { - throw new ServiceLayerException("The content-type " + contentType + " in site " + siteId + - " can't be deleted because there is content using it"); + throw new ContentTypeUsageException(siteId, contentType); } files.addAll(usage.getContent()); @@ -276,16 +365,16 @@ private FileVisitResult visitContentTypeFile(final Path file, final List } protected String getContentTypePath(String contentType) { - return normalize(contentTypeBasePathPattern.replaceFirst("\\{content-type}", contentType)); + return normalize(contentTypeBasePathPattern.replaceFirst(PATTERN_CONTENT_TYPE, contentType)); } /** * Get preview image filename extract from form-definition.xml * - * @param siteId - * @param contentTypeId + * @param siteId the site id + * @param contentTypeId the content type id * @return preview image filename - * @throws ServiceLayerException + * @throws ServiceLayerException if there is any error reading the content type definition */ protected String getContentTypePreviewImageFilename(String siteId, String contentTypeId) throws ServiceLayerException { Document definition = getFormDefinitionDocument(siteId, contentTypeId); @@ -302,10 +391,10 @@ protected String getContentTypePreviewImageFilename(String siteId, String conten /** * Get form-definition.xml as Document of a content type * - * @param siteId - * @param contentTypeId + * @param siteId the site id + * @param contentTypeId the content type id * @return Document of form-definition.xml - * @throws ServiceLayerException + * @throws ServiceLayerException if there is any error reading the content type definition or if the definition file does not exist */ @RequireSiteExists protected Document getFormDefinitionDocument(@SiteId String siteId, String contentTypeId) throws ServiceLayerException { diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgrader.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgrader.java new file mode 100644 index 0000000000..2a4644de7a --- /dev/null +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgrader.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.impl.v2.upgrade.operations.contentType; + +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.configuration2.HierarchicalConfiguration; +import org.craftercms.commons.upgrade.exception.UpgradeException; +import org.craftercms.studio.api.v2.utils.StudioConfiguration; +import org.craftercms.studio.impl.v2.upgrade.StudioUpgradeContext; +import org.craftercms.studio.impl.v2.upgrade.operations.site.BatchXsltFileUpgradeOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.beans.ConstructorProperties; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME; + +/** + * Upgrader to merge config.xml into form-definition.xml files for content types. + */ +public class ContentTypeConfigMergeUpgrader extends BatchXsltFileUpgradeOperation { + private static final Logger logger = LoggerFactory.getLogger(ContentTypeConfigMergeUpgrader.class); + + protected static final String CONFIG_FILE_PARAM = "configFileName"; + private String configFileName; + + @ConstructorProperties("studioConfiguration") + public ContentTypeConfigMergeUpgrader(StudioConfiguration studioConfiguration) { + super(studioConfiguration); + } + + @Override + protected void doInit(final HierarchicalConfiguration config) { + super.doInit(config); + configFileName = studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME); + } + + @Override + public void doExecute(StudioUpgradeContext context) throws UpgradeException { + super.doExecute(context); + Path repositoryRoot = context.getRepositoryPath(); + for (String deletedFile : ListUtils.emptyIfNull(deletedFiles)) { + logger.info("Deleting config file after merging: {}", deletedFile); + try { + Files.deleteIfExists(repositoryRoot.resolve(deletedFile)); + } catch (IOException e) { + throw new UpgradeException("Error deleting config file after merging: " + deletedFile, e); + } + } + } + + @Override + protected void executeTemplate(StudioUpgradeContext context, String formDefinitionPath, OutputStream os) throws UpgradeException { + logger.info("Executing config merge template for form definition: {}", formDefinitionPath); + super.executeTemplate(context, formDefinitionPath, os); + + Path configFilePath = Path.of(formDefinitionPath).resolveSibling(configFileName); + trackDeletedFiles(configFilePath.toString()); + } + + @Override + protected Map getTemplateParameters(StudioUpgradeContext context, String formDefinitionPath) { + Map params = new HashMap<>(super.getTemplateParameters(context, formDefinitionPath)); + params.put(CONFIG_FILE_PARAM, Path.of(formDefinitionPath).resolveSibling(configFileName)); + return params; + } +} diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractXsltFileUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractXsltFileUpgradeOperation.java index db74f7629f..008eb79d57 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractXsltFileUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractXsltFileUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -82,7 +82,7 @@ protected void executeTemplate(StudioUpgradeContext context, String path, Output try (InputStream templateIs = template.getInputStream(); InputStream sourceIs = Files.newInputStream(file)) { logger.info("Apply the XSLT template '{}' to file '{}' in site '{}'", template, path, site); - Map params = Map.of(PARAM_KEY_SITE, site, PARAM_KEY_VERSION, nextVersion); + Map params = getTemplateParameters(context, path); XsltUtils.executeTemplate(templateIs, params, getURIResolver(context), sourceIs, os); trackChangedFiles(path); } catch (Exception e) { @@ -93,6 +93,18 @@ protected void executeTemplate(StudioUpgradeContext context, String path, Output } } + /** + * Gets the parameters to be passed to the XSLT template. By default, it includes the site name and the next version, + * but it can be overridden by subclasses to provide additional parameters if needed. + * + * @param context the upgrade context, which can be used to get additional information for the parameters if needed + * @param path the path of the file being upgraded + * @return a map of parameter names and values to be passed to the XSLT template + */ + protected Map getTemplateParameters(StudioUpgradeContext context, String path) { + return Map.of(PARAM_KEY_SITE, context.getTarget(), PARAM_KEY_VERSION, nextVersion); + } + protected URIResolver getURIResolver(StudioUpgradeContext context) { return (href, base) -> { try { @@ -101,7 +113,6 @@ protected URIResolver getURIResolver(StudioUpgradeContext context) { logger.info("Failed to create a resolver for referencing documents inside XSLT forms", e); return null; } - }; } } diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/BatchXsltFileUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/BatchXsltFileUpgradeOperation.java index d818d05a25..70a5345b3f 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/BatchXsltFileUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/BatchXsltFileUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,6 +16,13 @@ package org.craftercms.studio.impl.v2.upgrade.operations.site; +import org.apache.commons.configuration2.HierarchicalConfiguration; +import org.craftercms.commons.upgrade.exception.UpgradeException; +import org.craftercms.studio.api.v2.utils.StudioConfiguration; +import org.craftercms.studio.impl.v2.upgrade.StudioUpgradeContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; @@ -23,15 +30,6 @@ import java.nio.file.StandardCopyOption; import java.util.stream.Stream; -import org.apache.commons.configuration2.HierarchicalConfiguration; -import org.craftercms.commons.upgrade.exception.UpgradeException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.impl.v2.upgrade.StudioUpgradeContext; - -import javax.sql.DataSource; - import static org.craftercms.studio.api.v2.utils.StudioUtils.getStudioTemporaryFilesRoot; /** @@ -54,7 +52,7 @@ public class BatchXsltFileUpgradeOperation extends AbstractXsltFileUpgradeOperat protected String regex; - public BatchXsltFileUpgradeOperation(StudioConfiguration studioConfiguration, DataSource dataSource) { + public BatchXsltFileUpgradeOperation(StudioConfiguration studioConfiguration) { super(studioConfiguration); } @@ -64,24 +62,33 @@ protected void doInit(final HierarchicalConfiguration config) { regex = config.getString(CONFIG_KEY_REGEX); } + /** + * Finds all files in the repository that match the regex. + * + * @param repository the repository path + * @return a stream of paths that match the regex + * @throws IOException if an error occurs while searching for files + */ + public Stream getPaths(Path repository) throws IOException { + return Files.find(repository, Integer.MAX_VALUE, + (path, attrs) -> repository.relativize(path).toString().matches(regex)); + } + @Override public void doExecute(final StudioUpgradeContext context) throws UpgradeException { var site = context.getTarget(); logger.debug("Find files that match the regex '{}' in site '{}'", regex, site); Path repository = context.getRepositoryPath(); - try (Stream paths = Files.find(repository, Integer.MAX_VALUE, - (path, attrs) -> repository.relativize(path).toString().matches(regex))) { + try (Stream paths = getPaths(repository)) { paths.forEach(path -> { logger.debug("Execute the XSLT template against site '{}' path '{}'", site, path); try { - Path temp = Files.createTempFile(getStudioTemporaryFilesRoot(), "upgrade-manager", "xslt"); + Path temp = Files.createTempFile(getStudioTemporaryFilesRoot(), "upgrade-manager", ".xslt"); try { OutputStream os = Files.newOutputStream(temp); executeTemplate(context, repository.relativize(path).toString(), os); os.close(); - if (Files.size(temp) > 0) { - Files.move(temp, path, StandardCopyOption.REPLACE_EXISTING); - } + replaceFile(path, temp); } finally { Files.deleteIfExists(temp); } @@ -94,4 +101,17 @@ public void doExecute(final StudioUpgradeContext context) throws UpgradeExceptio } } + /** + * Replaces the original file with the transformed file if the transformed file is not empty. + * + * @param path the original file path + * @param temp the transformed file path + * @throws IOException if an error occurs while replacing the file + */ + protected void replaceFile(Path path, Path temp) throws IOException { + if (Files.size(temp) > 0) { + Files.move(temp, path, StandardCopyOption.REPLACE_EXISTING); + } + } + } diff --git a/src/main/java/org/craftercms/studio/impl/v2/utils/Wrapper.java b/src/main/java/org/craftercms/studio/impl/v2/utils/Wrapper.java new file mode 100644 index 0000000000..cca58946f7 --- /dev/null +++ b/src/main/java/org/craftercms/studio/impl/v2/utils/Wrapper.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.impl.v2.utils; + +/** + * A simple wrapper class to hold a value of type T. This can be used to work + * around the fact that Java does not to modify variables from within lambda expressions or anonymous classes. + * + * @param + */ +public class Wrapper { + private T value; + + public T get() { + return value; + } + + public void set(T value) { + this.value = value; + } + + public boolean hasValue() { + return this.value != null; + } +} diff --git a/src/main/java/org/craftercms/studio/impl/v2/utils/db/DBUtils.java b/src/main/java/org/craftercms/studio/impl/v2/utils/db/DBUtils.java index a255343166..05eddba699 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/utils/db/DBUtils.java +++ b/src/main/java/org/craftercms/studio/impl/v2/utils/db/DBUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,6 +16,7 @@ package org.craftercms.studio.impl.v2.utils.db; +import org.craftercms.studio.impl.v2.utils.Wrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.PlatformTransactionManager; @@ -158,19 +159,4 @@ public interface ThrowingRunnable { void run() throws Exception; } - private static class Wrapper { - private T value; - - public T get() { - return value; - } - - public void set(T value) { - this.value = value; - } - - public boolean hasValue() { - return this.value != null; - } - } } diff --git a/src/main/java/org/craftercms/studio/model/contentType/ContentType.java b/src/main/java/org/craftercms/studio/model/contentType/ContentType.java new file mode 100644 index 0000000000..d35c794488 --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/contentType/ContentType.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.contentType; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.craftercms.studio.api.v2.dal.security.NormalizedRole; +import org.craftercms.studio.api.v2.utils.StudioUtils; + +import java.util.*; + +import static java.util.Collections.emptyList; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + +/** + * Represents a content type in the system. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContentType { + @JsonAlias("content-type") + @JsonProperty("id") + protected String id; + @JsonAlias("title") + @JsonProperty("label") + protected String label; + @JsonAlias("allowed-roles") + @JsonProperty("allowedRoles") + protected Collection allowedRoles = emptyList(); + @JsonAlias("delete-dependencies") + @JsonProperty("deleteDependencies") + protected List deleteDependencies = emptyList(); + @JsonAlias("copy-dependencies") + @JsonProperty("copyDependencies") + protected List copyDependencies = emptyList(); + protected boolean previewable; + protected String imageThumbnail; + protected boolean noThumbnail; + // Because both excludes and excludes need to be set together, we use a single property for both, and ignore it during serialization + // so the JSON representation still has the same structure as before, with separate includes and excludes properties + @JsonProperty(value = "paths", access = JsonProperty.Access.WRITE_ONLY) + protected PathIncludeExcludes pathIncludeExcludes; + protected boolean quickCreate; + protected String quickCreatePath; + + public Collection getAllowedRoles() { + return allowedRoles; + } + + public void setAllowedRoles(Collection allowedRoles) { + Set normalizedRoles = new HashSet<>(); + for (String role : emptyIfNull(allowedRoles)) { + normalizedRoles.add(new NormalizedRole(role)); + } + this.allowedRoles = normalizedRoles; + } + + public List getCopyDependencies() { + return copyDependencies; + } + + public void setCopyDependencies(List copyDependencies) { + this.copyDependencies = copyDependencies; + } + + public List getDeleteDependencies() { + return deleteDependencies; + } + + public void setDeleteDependencies(List deleteDependencies) { + this.deleteDependencies = deleteDependencies; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImageThumbnail() { + return imageThumbnail; + } + + public void setImageThumbnail(String imageThumbnail) { + this.imageThumbnail = imageThumbnail; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public boolean isNoThumbnail() { + return noThumbnail; + } + + public void setNoThumbnail(boolean noThumbnail) { + this.noThumbnail = noThumbnail; + } + + public Collection getPathIncludes() { + return emptyIfNull(pathIncludeExcludes.includes()).stream() + .map(PathPattern::getPattern) + .toList(); + } + + public Collection getPathExcludes() { + return emptyIfNull(pathIncludeExcludes.excludes()).stream() + .map(PathPattern::getPattern) + .toList(); + } + + public void setPathIncludeExcludes(PathIncludeExcludes pathIncludeExcludes) { + this.pathIncludeExcludes = pathIncludeExcludes; + } + + public boolean isPreviewable() { + return previewable; + } + + public void setPreviewable(boolean previewable) { + this.previewable = previewable; + } + + public boolean isQuickCreate() { + return quickCreate; + } + + public void setQuickCreate(boolean quickCreate) { + this.quickCreate = quickCreate; + } + + public String getQuickCreatePath() { + return quickCreatePath; + } + + public void setQuickCreatePath(String quickCreatePath) { + this.quickCreatePath = quickCreatePath; + } + + public Type getType() { + return StudioUtils.getContentTypeTypeById(id); + } + + public enum Type { + page, component, unknown + } +} diff --git a/src/main/java/org/craftercms/studio/model/contentType/CopyDependency.java b/src/main/java/org/craftercms/studio/model/contentType/CopyDependency.java new file mode 100644 index 0000000000..e29b6cd393 --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/contentType/CopyDependency.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.contentType; + +/** + * Represents a copy dependency for a content type. + * + * @param pattern the pattern to match the dependencies to be copied + * @param target the target location where the dependencies should be copied to + */ +public record CopyDependency(String pattern, + String target) { +} diff --git a/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java b/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java new file mode 100644 index 0000000000..8e3b002497 --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.contentType; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a delete dependency for a content type. + * + * @param pattern the pattern to match the dependencies to be deleted + * @param removeEmptyFolder a flag indicating whether to remove empty folders after deletion + */ +public record DeleteDependency(String pattern, + @JsonAlias("remove-empty-folder") boolean removeEmptyFolder) { +} diff --git a/src/main/java/org/craftercms/studio/model/contentType/PathIncludeExcludes.java b/src/main/java/org/craftercms/studio/model/contentType/PathIncludeExcludes.java new file mode 100644 index 0000000000..f0d245ce0e --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/contentType/PathIncludeExcludes.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.contentType; + +import java.util.Collection; + +/** + * Represents the includes and excludes for content type paths. + * + * @param includes the included path patterns for the content type + * @param excludes the excluded path patterns for the content type + */ +public record PathIncludeExcludes(Collection includes, + Collection excludes) { +} diff --git a/src/main/java/org/craftercms/studio/model/contentType/PathPattern.java b/src/main/java/org/craftercms/studio/model/contentType/PathPattern.java new file mode 100644 index 0000000000..a0889f9d7d --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/contentType/PathPattern.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.contentType; + +/** + * Represents a pattern for content type paths includes and excludes. + * This is a class and not a record to avoid issues with Jackson deserialization when used in + * a Collection. See {@link PathIncludeExcludes} + */ +public class PathPattern { + private final String pattern; + + public PathPattern(String pattern) { + this.pattern = pattern; + } + + public String getPattern() { + return pattern; + } +} diff --git a/src/main/java/org/craftercms/studio/model/rest/ApiResponse.java b/src/main/java/org/craftercms/studio/model/rest/ApiResponse.java index eca1259be9..eca935a6fb 100644 --- a/src/main/java/org/craftercms/studio/model/rest/ApiResponse.java +++ b/src/main/java/org/craftercms/studio/model/rest/ApiResponse.java @@ -208,9 +208,14 @@ public class ApiResponse { public static final ApiResponse LOGGER_NOT_FOUND = new ApiResponse(53000, "The logger was not found", "Check if you sent in the right logger name or " + "add 'createIfAbsent=true' parameter to create the logger if it does not exist", StringUtils.EMPTY); + // 54000 - 55000 public static final ApiResponse CONFIGURATION_PROFILE_NOT_FOUND = new ApiResponse(54000, "The profile was not found", "Check if you sent in the right profileId name", StringUtils.EMPTY); + // 55000 - 56000 + public static final ApiResponse CONTENT_TYPE_IN_USE = new ApiResponse(55000, "The content type cannot be deleted because it is still in use by content items", + "Check if you sent in the right content type id or add 'deleteDependencies' to force delete", StringUtils.EMPTY); + private int code; private String message; private String remedialAction; diff --git a/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java b/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java new file mode 100644 index 0000000000..b66b1537d8 --- /dev/null +++ b/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.model.rest.contentType; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.craftercms.commons.validation.annotations.param.ValidConfigurationPath; + +/** + * Request for deleting a content-type. + */ +@JsonIgnoreProperties +public class DeleteContentTypeRequest { + @ValidConfigurationPath + protected String contentType; + + protected boolean deleteDependencies; + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public boolean isDeleteDependencies() { + return deleteDependencies; + } + + public void setDeleteDependencies(boolean deleteDependencies) { + this.deleteDependencies = deleteDependencies; + } + +} diff --git a/src/main/resources/crafter/studio/extension/rendering-overlay-context.xml b/src/main/resources/crafter/studio/extension/rendering-overlay-context.xml index ab3343cc3f..0b60cce11e 100644 --- a/src/main/resources/crafter/studio/extension/rendering-overlay-context.xml +++ b/src/main/resources/crafter/studio/extension/rendering-overlay-context.xml @@ -1,6 +1,6 @@ diff --git a/src/main/resources/crafter/studio/studio-upgrade-context.xml b/src/main/resources/crafter/studio/studio-upgrade-context.xml index 54ea367b67..1c1e4f9570 100644 --- a/src/main/resources/crafter/studio/studio-upgrade-context.xml +++ b/src/main/resources/crafter/studio/studio-upgrade-context.xml @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/crafter/studio/upgrade/pipelines.yaml b/src/main/resources/crafter/studio/upgrade/pipelines.yaml index 0164c34900..5fa588ad08 100644 --- a/src/main/resources/crafter/studio/upgrade/pipelines.yaml +++ b/src/main/resources/crafter/studio/upgrade/pipelines.yaml @@ -763,6 +763,13 @@ pipelines: - pattern: "\\._toQuery\\(\\)" replacement: '.toQuery()' commitDetails: Upgrade to OpenSearch 3 in site scripts + - currentVersion: 5.0.0.1 + nextVersion: 5.0.0.2 + operations: + - type: contentTypeConfigMergeUpgrader + regex: config/studio/content-types/.+/form-definition\.xml + template: crafter/studio/upgrade/5.0.x/content-type/content-type-merge-v5.0.0.2.xslt + commitDetails: Merge content type config.xml into form-definition.xml and remove config.xml files # Pipeline to upgrade blueprints blueprint: diff --git a/src/main/webapp/default-site/scripts/api/ContentServices.groovy b/src/main/webapp/default-site/scripts/api/ContentServices.groovy index ff6c276506..b69caf3238 100644 --- a/src/main/webapp/default-site/scripts/api/ContentServices.groovy +++ b/src/main/webapp/default-site/scripts/api/ContentServices.groovy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -66,11 +66,6 @@ class ContentServices { return contentServicesImpl.getContentVersionAtPath(site, path, version) } - static getContentType(context, site, type) { - def contentTypeServicesImpl = ServiceFactory.getContentTypeServices(context); - return contentTypeServicesImpl.getContentType(site, type) - } - static reorderItems(context, site, path, before, after) { def contentServicesImpl = ServiceFactory.getContentServices(context); return contentServicesImpl.reorderItems(site, path, before, after); diff --git a/src/main/webapp/default-site/scripts/api/ContentTypeServices.groovy b/src/main/webapp/default-site/scripts/api/ContentTypeServices.groovy deleted file mode 100644 index 2efffde3e3..0000000000 --- a/src/main/webapp/default-site/scripts/api/ContentTypeServices.groovy +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package scripts.api -/** - * content type services - */ -class ContentTypeServices { - - /** - * create the context object - * @param applicationContext - studio application's contect (spring container etc) - * @param request - web request if in web request context - */ - static createContext(applicationContext, request) { - return ServiceFactory.createContext(applicationContext, request) - } - - /** - * get all content types for a given site - * @param site - the project ID - * @param searchable - include non-searchable types (true/false) - */ - static getContentTypes(context, site, searchable) { - def contentTypeServiceImpl = ServiceFactory.getContentTypeServices(context) - return contentTypeServiceImpl.getContentTypes(site, searchable) - } - - /** - * get allowed content types for a given path - * @param site - the project ID - * @param path - the path - */ - static getAllowedContentTypesForPath(context, site, path) { - def contentTypeServiceImpl = ServiceFactory.getContentTypeServices(context) - return contentTypeServiceImpl.getAllowedContentTypesForPath(site, path) - } - - /** - * Get a content type definition - * @param site - the Project ID - * @param type - the content type - */ - def getContentType(site, type) { - - } -} diff --git a/src/main/webapp/default-site/scripts/api/ServiceFactory.groovy b/src/main/webapp/default-site/scripts/api/ServiceFactory.groovy index 266ff280a3..c16d36750b 100644 --- a/src/main/webapp/default-site/scripts/api/ServiceFactory.groovy +++ b/src/main/webapp/default-site/scripts/api/ServiceFactory.groovy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,13 +16,12 @@ package scripts.api -import scripts.libs.Cookies import scripts.api.impl.content.SpringContentServices -import scripts.api.impl.content.SpringContentTypeServices import scripts.api.impl.content.SpringPageNavigationOrderServices import scripts.api.impl.security.SpringSecurityServices import scripts.api.impl.site.SpringSiteServices import scripts.api.impl.user.SpringUserServices +import scripts.libs.Cookies /** * Class is a factory used by the API wrappers to find their implementation @@ -53,13 +52,6 @@ class ServiceFactory { return new SpringContentServices(context) } - /** - * return the implementation for content type services - */ - static getContentTypeServices(context) { - return new SpringContentTypeServices(context) - } - /** * return the implementation for security services * diff --git a/src/main/webapp/default-site/scripts/api/impl/content/SpringContentTypeServices.groovy b/src/main/webapp/default-site/scripts/api/impl/content/SpringContentTypeServices.groovy deleted file mode 100644 index 85dc3e4581..0000000000 --- a/src/main/webapp/default-site/scripts/api/impl/content/SpringContentTypeServices.groovy +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @author Dejan Brkic - */ -package scripts.api.impl.content; - -/** - * content type services - */ -class SpringContentTypeServices { - - static CONTENT_TYPE_SERVICES_BEAN = "cstudioContentTypeService" - - def context = null - - def SpringContentTypeServices(context) { - this.context = context - } - - def getContentTypes(site, searchable) { - def springBackedService = this.context.applicationContext.get(CONTENT_TYPE_SERVICES_BEAN) - return springBackedService.getAllContentTypes(site, searchable) - } - - def getContentType(site, type) { - def springBackedService = this.context.applicationContext.get(CONTENT_TYPE_SERVICES_BEAN) - return springBackedService.getContentType(site, type) - } - - def getAllowedContentTypesForPath(site, path) { - def springBackedService = this.context.applicationContext.get(CONTENT_TYPE_SERVICES_BEAN) - return springBackedService.getAllowedContentTypesForPath(site, path); - } -} diff --git a/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-type.get.groovy b/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-type.get.groovy deleted file mode 100644 index 5376294cdb..0000000000 --- a/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-type.get.groovy +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @author Dejan Brkic - */ - -import org.apache.commons.lang3.StringUtils -import scripts.api.ContentServices - -def result = [:] -def site = params.site_id -def type = params.type - -/** Validate Parameters */ -def invalidParams = false -def paramsList = [] - -// site_id -try { - if (StringUtils.isEmpty(site)) { - site = params.site - if (StringUtils.isEmpty(site)) { - invalidParams = true - paramsList.add("site_id") - } - } -} catch (Exception e) { - invalidParams = true - paramsList.add("site_id") -} - -if (invalidParams) { - response.setStatus(400) - result.message = "Invalid parameter(s): " + paramsList -} else { - def context = ContentServices.createContext(applicationContext, request) - - result = ContentServices.getContentType(context, site, type) - -} -return result diff --git a/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-types.get.groovy b/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-types.get.groovy deleted file mode 100644 index b970ee355b..0000000000 --- a/src/main/webapp/default-site/scripts/rest/api/1/content/get-content-types.get.groovy +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @author Dejan Brkic - */ - -import org.apache.commons.lang3.StringUtils -import scripts.api.ContentTypeServices - -def result = [:] -def site = params.site -def path = params.path - -/** Validate Parameters */ -def invalidParams = false -def paramsList = [] - -// site_id -try { - if (StringUtils.isEmpty(site)) { - site = params.site - if (StringUtils.isEmpty(site)) { - invalidParams = true - paramsList.add("site_id") - } - } -} catch (Exception e) { - invalidParams = true - paramsList.add("site_id") -} - -if (invalidParams) { - response.setStatus(400) - result.message = "Invalid parameter(s): " + paramsList -} else { - def context = ContentTypeServices.createContext(applicationContext, request) - if (path != null) { - result = ContentTypeServices.getAllowedContentTypesForPath(context, site, path) - } else { - result = ContentTypeServices.getContentTypes(context, site, true) - } - -} -return result diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/config.xml deleted file mode 100644 index 4f78e08624..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/articles-widget
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - component-articles-widget.png - - - ^/site/components/articles-widget/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/form-definition.xml index a2f6e746e2..f2015e3ae5 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/articles-widget/form-definition.xml @@ -1,5 +1,6 @@ + -
- Articles Widget - - component - /component/articles-widget - component-articles-widget.png - false - - - - display-template - - /templates/web/components/articles-widget.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Component - Articles Widget Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - articles - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - checkbox - disabled - articles - Disable Component - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - node-selector - scripts_o - - Controllers - The controller script(s) that will be executed before the component is rendered - - - - - minSize - 1 - int - - - maxSize - - int - - - itemManager - scripts - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - input - title_t - articles - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - numeric-input - max_articles_i - articles - Max Articles - - - - - - size - 3 - int - - - maxlength - 3 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - -
-
- - - shared-content - scripts - Scripts - item - - - repoPath - /scripts/components - undefined - - - browsePath - - undefined - - - type - - undefined - - - - + Articles Widget + + component + /component/articles-widget + component-articles-widget.png + false + + + + display-template + + /templates/web/components/articles-widget.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Component - Articles Widget Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + articles + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + checkbox + disabled + articles + Disable Component + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + node-selector + scripts_o + + Controllers + The controller script(s) that will be executed before the component is rendered + + + + + minSize + 1 + int + + + maxSize + + int + + + itemManager + scripts + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + input + title_t + articles + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + numeric-input + max_articles_i + articles + Max Articles + + + + + + size + 3 + int + + + maxlength + 3 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + +
+
+ + + shared-content + scripts + Scripts + item + + + repoPath + /scripts/components + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + false + false + + + ^/site/components/articles-widget/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/config.xml deleted file mode 100644 index 1222a096ac..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/contact-widget
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - component-contact-widget.png - - - ^/site/components/contacts/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/form-definition.xml index f2ae4c2f05..27c09eff07 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/contact-widget/form-definition.xml @@ -1,5 +1,6 @@ + -
- Contact Widget - - component - /component/contact-widget - component-contact-widget.png - false - - - - display-template - - /templates/web/components/contact-widget.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Component - Contact Widget Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Component - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Content - - true - - - input - title_t - - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - text_html - - Text - - - - - - height - - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - uploadImages,existingImages - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - input - email_s - - Email - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - phone_s - - Phone - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - address_html - - Address - - - - - - height - - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - uploadImages,existingImages - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - -
-
- - - img-desktop-upload - uploadImages - Upload Images - image - - - repoPath - /static-assets/images - content-path-input - - - - - img-repository-upload - existingImages - Existing Images - image - - - repoPath - /static-assets/images - content-path-input - - - useSearch - false - boolean - - - - + Contact Widget + + component + /component/contact-widget + component-contact-widget.png + false + + + + display-template + + /templates/web/components/contact-widget.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Component - Contact Widget Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Component + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + input + title_t + + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + text_html + + Text + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + uploadImages,existingImages + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + input + email_s + + Email + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + phone_s + + Phone + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + address_html + + Address + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + uploadImages,existingImages + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + +
+
+ + + img-desktop-upload + uploadImages + Upload Images + image + + + repoPath + /static-assets/images + content-path-input + + + + + img-repository-upload + existingImages + Existing Images + image + + + repoPath + /static-assets/images + content-path-input + + + useSearch + false + boolean + + + + + false + false + + + ^/site/components/contacts/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/config.xml deleted file mode 100644 index 06d4c828ae..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/feature
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - component-feature.png - - - ^/site/components/features/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/form-definition.xml index 65a4e86c00..e6b48a8d05 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/feature/form-definition.xml @@ -1,5 +1,6 @@ + -
- Feature - - component - /component/feature - component-feature.png - false - - - - display-template - - /templates/web/components/feature.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Component - Feature Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Component - - false - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Content - - true - - - dropdown - icon_s - icon_s - Icon - - fa-closed-captioning far - - - - datasource - feature_icons - datasource:item - - - emptyvalue - - boolean - - - readonly - - boolean - - - - - required - - boolean - - - - - input - title_t - - Title - - Feature Title - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - body_html - - Body - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. - - - - height - - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - uploadImages,existingImages - datasource:image - - - videoManager - - datasource:video - - - width - - int - - - autoGrow - false - boolean - - - fileManager - - datasource:item - - - - - required - - boolean - - - - -
-
- - - simpleTaxonomy - feature_icons - Feature Icons - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/feature-icons.xml - undefined - - - - - img-desktop-upload - uploadImages - Upload Images - image - - - repoPath - /static-assets/images - content-path-input - - - - - img-repository-upload - existingImages - Existing Images - image - - - repoPath - /static-assets/images - content-path-input - - - useSearch - false - boolean - - - - + Feature + + component + /component/feature + component-feature.png + false + + + + display-template + + /templates/web/components/feature.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Component - Feature Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Component + + false + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + dropdown + icon_s + icon_s + Icon + + fa-closed-captioning far + + + + datasource + feature_icons + datasource:item + + + emptyvalue + + boolean + + + readonly + + boolean + + + + + required + true + boolean + + + + + input + title_t + + Title + + Feature Title + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + body_html + + Body + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + uploadImages,existingImages + datasource:image + + + videoManager + + datasource:video + + + width + + int + + + autoGrow + false + boolean + + + fileManager + + datasource:item + + + + + required + true + boolean + + + + +
+
+ + + simpleTaxonomy + feature_icons + Feature Icons + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/feature-icons.xml + undefined + + + + + img-desktop-upload + uploadImages + Upload Images + image + + + repoPath + /static-assets/images + content-path-input + + + + + img-repository-upload + existingImages + Existing Images + image + + + repoPath + /static-assets/images + content-path-input + + + useSearch + false + boolean + + + + + false + false + + + ^/site/components/features/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/config.xml deleted file mode 100644 index 32aba74823..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/header
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - component-header.png - - - ^/site/components/headers/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/form-definition.xml index 639fe2b8a4..4ca3a4e8f6 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/header/form-definition.xml @@ -1,5 +1,6 @@ + -
- Header - - component - /component/header - component-header.png - false - - - - display-template - - /templates/web/components/header.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Component - Header Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Component - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Business Name and Logo - - true - - - image-picker - logo_s - header - Logo - - - - - - width - { "exact":"", "min":"", "max":"" + Header + + component + /component/header + component-header.png + false + + + + display-template + + /templates/web/components/header.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Component - Header Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Component + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Business Name and Logo + + true + + + image-picker + logo_s + header + Logo + + + + + + width + { "exact":"", "min":"", "max":"" } - range - - - height - { "exact":"", "min":"", "max":"" + range + + + height + { "exact":"", "min":"", "max":"" } - range - - - thumbnailWidth - - int - - - thumbnailHeight - - int - - - imageManager - existingimages,uploadimage,existing_images,upload_image - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - input - logo_text_t - hero - Logo Alt Text - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - business_name_s - header - Business Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - -
-
- Social Media Links - - true - - - node-selector - socialMediaWidget_o - - Social Media Widget - - - - - - minSize - - int - - - maxSize - 1 - int - - - itemManager - socialMedia - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - useMVS - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images - undefined - - - - - img-desktop-upload - upload_image - Upload Images - image - - - repoPath - /static-assets/item/images/{yyyy}/{mm}/{dd}/ - undefined - - - - - components - socialMedia - Social Media - item - - - allowShared - true - boolean - - - allowEmbedded - true - boolean - - - enableBrowse - true - boolean - - - enableSearch - false - boolean - - - baseRepositoryPath - /site/components - string - - - baseBrowsePath - /site/components - string - - - contentTypes - /component/social-media-widget - contentTypes - - - tags - - string - - - - + range +
+ + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + existing_images,upload_image + datasource:image + + + readonly + + boolean + +
+ + + required + false + boolean + + +
+ + input + logo_text_t + hero + Logo Alt Text + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + false + boolean + + + pattern + + string + + + + + input + business_name_s + header + Business Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + +
+
+
+ Social Media Links + + true + + + node-selector + socialMediaWidget_o + + Social Media Widget + + + + + + minSize + + int + + + maxSize + 1 + int + + + itemManager + socialMedia + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + useMVS + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images + undefined + + + + + img-desktop-upload + upload_image + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + components + socialMedia + Social Media + item + + + allowShared + true + boolean + + + allowEmbedded + true + boolean + + + enableBrowse + true + boolean + + + enableSearch + false + boolean + + + baseRepositoryPath + /site/components + string + + + baseBrowsePath + /site/components + string + + + contentTypes + /component/social-media-widget + contentTypes + + + tags + + string + + + + + false + false + + + ^/site/components/headers/.* + +
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/config.xml deleted file mode 100644 index 26e2b88680..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/left-rail
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - component-left-rail.png - - - ^/site/components/left-rails/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/form-definition.xml index 7dc6385aba..d6baf18adb 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/left-rail/form-definition.xml @@ -1,5 +1,6 @@ + -
- Left Rail - - component - /component/left-rail - component-left-rail.png - false - - - - display-template - - /templates/web/components/left-rail.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Component - Left Rail Properties - - true - - - file-name - file-name - left-rail - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - left-rail - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - checkbox - disabled - left-rail - Disable Component - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Widgets - - true - - - node-selector - widgets_o - left-rail - Widgets - - - - - - minSize - 0 - int - - - maxSize - - int - - - itemManager - components - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- - - shared-content - components - Components - item - - - repoPath - /site/components - undefined - - - browsePath - - undefined - - - type - - undefined - - - - + Left Rail + + component + /component/left-rail + component-left-rail.png + false + + + + display-template + + /templates/web/components/left-rail.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Component - Left Rail Properties + + true + + + file-name + file-name + left-rail + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + left-rail + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + checkbox + disabled + left-rail + Disable Component + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Widgets + + true + + + node-selector + widgets_o + left-rail + Widgets + + + + + + minSize + 0 + int + + + maxSize + + int + + + itemManager + components + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ + + shared-content + components + Components + item + + + repoPath + /site/components + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + false + false + + + ^/site/components/left-rails/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/config.xml deleted file mode 100644 index 25272dc5a7..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/level-descriptor
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - section-defaults.png - - - ^/site/website/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/form-definition.xml index 1d3a984097..2a84d11a57 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/level-descriptor/form-definition.xml @@ -1,5 +1,6 @@ + -
- Section Defaults - Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" - component - /component/level-descriptor - section-defaults.png - false - - - - display-template - - - template - - - no-template-required - - true - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Section Defaults Properties - - true - - - file-name - file-name - - File Name - - crafter-level-descriptor.level - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - true - boolean - - - - - - - node-selector - header_o - - Header - - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-header - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - node-selector - left_rail_o - - Left Rail - - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-left-rail - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- - - shared-content - components-header - Components Header - item - - - repoPath - /site/components/headers/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - - shared-content - components-left-rail - Components Left Rail - item - - - repoPath - /site/components/left-rails/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - + Section Defaults + Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" + component + /component/level-descriptor + section-defaults.png + false + + + + display-template + + + template + + + no-template-required + + true + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Section Defaults Properties + + true + + + file-name + file-name + + File Name + + crafter-level-descriptor.level + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + true + boolean + + + + + + node-selector + header_o + + Header + + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + false + false + + + ^/site/website/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/config.xml deleted file mode 100755 index 43057711c3..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/config.xml +++ /dev/null @@ -1,18 +0,0 @@ - - -
/component/social-media-widget
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - ^/site/components/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/form-definition.xml old mode 100755 new mode 100644 index 9cce9e6ce1..e82873ddcf --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/component/social-media-widget/form-definition.xml @@ -1,525 +1,532 @@ +
- Social Media Widget - - component - /component/social-media-widget - - false - - - - display-template - - /templates/web/components/social-media-widget.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Social Media Widget Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - input - header_s - - Header - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - escapeContent - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - repeat - accounts_o - - Accounts - - 1 - * - - - minOccurs - 0 - string - - - maxOccurs - * - string - - - - - dropdown - network_s - - Network - - - - - - datasource - networks - datasource:item - - - emptyvalue - - boolean - - - readonly - - boolean - - - - - required - - boolean - - - - - input - title_s - - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - escapeContent - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - url_s - - URL - - # - The full URL for your profile in the given social network - - - size - 150 - int - - - maxlength - 300 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - escapeContent - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - image-picker - icon_s - - Icon - Leave empty to use the default icon. If no icon is provided, the system will use the + Social Media Widget + + component + /component/social-media-widget + + false + + + + display-template + + /templates/web/components/social-media-widget.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Social Media Widget Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + input + header_s + + Header + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + escapeContent + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + repeat + accounts_o + + Accounts + + 1 + * + + + minOccurs + 0 + string + + + maxOccurs + * + string + + + + + dropdown + network_s + + Network + + + + + + datasource + networks + datasource:item + + + emptyvalue + + boolean + + + readonly + + boolean + + + + + required + true + boolean + + + + + input + title_s + + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + escapeContent + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + input + url_s + + URL + + # + The full URL for your profile in the given social network + + + size + 150 + int + + + maxlength + 300 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + escapeContent + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + image-picker + icon_s + + Icon + Leave empty to use the default icon. If no icon is provided, the system will use the built-in. - - - - - width - { "exact":"", "min":"", "max":"" + + + + + width + { "exact":"", "min":"", "max":"" } - range - - - height - { "exact":"", "min":"", "max":"" + range + + + height + { "exact":"", "min":"", "max":"" } - range - - - thumbnailWidth - - int - - - thumbnailHeight - - int - - - imageManager - imageUpload,imageFromRepository - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - - -
-
- Advanced Options - - false - - - numeric-input - iconsWidth_i - - Icons Width (in pixels) - - 24 - - - - size - 50 - int - - - maxValue - - float - - - minValue - - float - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - numeric-input - iconsHeight_i - - Icons Height (in pixels) - - 24 - - - - size - 50 - int - - - maxValue - - float - - - minValue - - float - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - checkbox - showItemsInline_b - - Show Items Inline - - true - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- - - img-repository-upload - imageFromRepository - Image From Repository - image - - - repoPath - /static-assets/images - content-path-input - - - useSearch - false - boolean - - - - - img-desktop-upload - imageUpload - Image Upload - image - - - repoPath - /static-assets/images/{objectId} - content-path-input - - - - - simpleTaxonomy - networks - Networks - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"Data Type","selected":false}] - dropdown - - - componentPath - /site/taxonomy/social-media-networks.xml - string - - - - + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + imageUpload,imageFromRepository + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + +
+
+
+
+
+
+ Advanced Options + + false + + + numeric-input + iconsWidth_i + + Icons Width (in pixels) + + 24 + + + + size + 50 + int + + + maxValue + + float + + + minValue + + float + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + numeric-input + iconsHeight_i + + Icons Height (in pixels) + + 24 + + + + size + 50 + int + + + maxValue + + float + + + minValue + + float + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + checkbox + showItemsInline_b + + Show Items Inline + + true + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ + + img-repository-upload + imageFromRepository + Image From Repository + image + + + repoPath + /static-assets/images + content-path-input + + + useSearch + false + boolean + + + + + img-desktop-upload + imageUpload + Image Upload + image + + + repoPath + /static-assets/images/{objectId} + content-path-input + + + + + simpleTaxonomy + networks + Networks + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"Data Type","selected":false}] + dropdown + + + componentPath + /site/taxonomy/social-media-networks.xml + string + + + + + false + true + + + ^/site/components/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/config.xml deleted file mode 100644 index 86ae812b09..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/article
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - true - true - true - /site/website/articles/{year}/{month} - false - page-article.png - - - ^/site/website/articles/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/form-definition.xml index bd4a56bad0..9d88054577 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/article/form-definition.xml @@ -1,5 +1,6 @@ + -
- Article - - page - /page/article - page-article.png - true - /site/website/articles/{year}/{month} - - - display-template - - /templates/web/pages/article.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Page Properties - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Page - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - title_t - core - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - header_o - core - Header - Default header is inherited from Section Defaults. Specify a new header to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-header - datasource:item - - - readonly - - boolean - - - disableFlattening - false - boolean - - - useSingleValueFilename - - boolean - - - contentTypes - /component/header - contentTypes - - - tags - - string - - - - - allowDuplicates - - boolean - - - - - node-selector - left_rail_o - - Left Rail - Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-left-rail - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - contentTypes - /component/left-rail - contentTypes - - - tags - - string - - - - - allowDuplicates - - boolean - - - - -
-
- Metadata - - true - - - checkbox-group - categories_o - - Categories - - - - - - datasource - categories - datasource:item - - - selectAll - true - boolean - - - readonly - - boolean - - - listDirection - [{"value":"horizontal","label":"Horizonal","selected":true},{"value":"vertical","label":"Vertical","selected":false}] - dropdown - - - - - minSize - - int - - - - - checkbox-group - segments_o - - Segments - - - - - - datasource - segments - datasource:item - - - selectAll - true - boolean - - - readonly - - boolean - - - - - minSize - - int - - - - - checkbox - featured_b - - Featured - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Content - - true - - - input - subject_t - subject - Subject - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - author_s - subject - Author - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - date-time - date_dt - - Date - - - - - - showDate - true - boolean - - - showTime - - boolean - - - showClear - true - boolean - - - showNowLink - true - boolean - - - populate - true - boolean - - - allowPastDate - true - boolean - - - populateDateExp - now - string - - - useCustomTimezone - false - boolean - - - readonly - - boolean - - - readonlyEdit - false - boolean - - - - - required - - boolean - - - - date_dt_tz - - - - textarea - summary_t - - Summary - - - - - - cols - 50 - int - - - rows - 5 - int - - - maxlength - 100000 - int - - - allowResize - true - boolean - - - readonly - - boolean - - - - - required - - boolean - - - - - image-picker - image_s - - Image - - - - - - width - { "exact":"", "min":"", "max":"" } - range - - - height - { "exact":"", "min":"", "max":"" } - range - - - thumbnailWidth - - int - - - thumbnailHeight - - int - - - imageManager - upload_images,existing_images - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - repeat - sections_o - article - Sections - - 1 - * - - - minOccurs - 1 - string - - - maxOccurs - * - string - - - - - rte - section_html - article - Section - - - - - - height - - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - upload_images,existing_images - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - - -
-
- - - shared-content - components-header - Components Header - item - - - repoPath - /site/components/headers - undefined - - - browsePath - - undefined - - - type - - undefined - - - enableCreateNew - true - boolean - - - enableBrowseExisting - true - boolean - - - enableSearchExisting - true - boolean - - - - - img-desktop-upload - upload_images - Upload Images - image - - - repoPath - /static-assets/item/images/{yyyy}/{mm}/{dd}/ - undefined - - - - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images - undefined - - - - - simpleTaxonomy - categories - Categories - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/categories.xml - undefined - - - - - simpleTaxonomy - segments - Segments - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/segments.xml - undefined - - - - - shared-content - components-left-rail - Components Left Rail - item - - - repoPath - /site/components/left-rails/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - enableCreateNew - true - boolean - - - enableBrowseExisting - true - boolean - - - enableSearchExisting - true - boolean - - - - + Article + + page + /page/article + page-article.png + true + /site/website/articles/{year}/{month} + + + display-template + + /templates/web/pages/article.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + core + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + node-selector + header_o + core + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + false + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/header + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/left-rail + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ Metadata + + true + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + listDirection + [{"value":"horizontal","label":"Horizonal","selected":true},{"value":"vertical","label":"Vertical","selected":false}] + dropdown + + + + + minSize + 1 + int + + + + + checkbox-group + segments_o + + Segments + + + + + + datasource + segments + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + 1 + int + + + + + checkbox + featured_b + + Featured + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + input + subject_t + subject + Subject + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + author_s + subject + Author + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + date-time + date_dt + + Date + + + + + + showDate + true + boolean + + + showTime + + boolean + + + showClear + true + boolean + + + showNowLink + true + boolean + + + populate + true + boolean + + + allowPastDate + true + boolean + + + populateDateExp + now + string + + + useCustomTimezone + false + boolean + + + readonly + + boolean + + + readonlyEdit + false + boolean + + + + + required + true + boolean + + + + date_dt_tz + + + + textarea + summary_t + + Summary + + + + + + cols + 50 + int + + + rows + 5 + int + + + maxlength + 100000 + int + + + allowResize + true + boolean + + + readonly + + boolean + + + + + required + true + boolean + + + + + image-picker + image_s + + Image + + + + + + width + { "exact":"", "min":"", "max":"" } + range + + + height + { "exact":"", "min":"", "max":"" } + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + repeat + sections_o + article + Sections + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + rte + section_html + article + Section + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images + undefined + + + + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + simpleTaxonomy + segments + Segments + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/segments.xml + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + true + false + + + ^/site/website/articles/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/config.xml deleted file mode 100644 index 876738af4e..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/category-landing
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - true - true - false - - false - page-category-landing.png - - - ^/site/website/(?!articles/)(.*) - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/form-definition.xml index 93d27bc620..b25ea2b6e5 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/category-landing/form-definition.xml @@ -1,5 +1,6 @@ + -
- Category Landing - - page - /page/category-landing - page-category-landing.png - false - - - - display-template - - /templates/web/pages/category-landing.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Page Properties - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Page - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - page-nav-order - placeInNav - - Place in Nav - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - navLabel - - Nav Label - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - escapeContent - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - title_t - - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - header_o - - Header - Default header is inherited from Section Defaults. Specify a new header to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-header - datasource:item - - - readonly - - boolean - - - disableFlattening - false - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - node-selector - left_rail_o - - Left Rail - Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-left-rail - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- Articles - - true - - - input - articles_title_t - articles - Articles Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - dropdown - category_s - articles - Category - - - - - - datasource - categories - datasource:item - - - emptyvalue - - boolean - - - readonly - - boolean - - - - - required - - boolean - - - - - numeric-input - max_articles_i - articles - Max Articles - - 10 - - - - size - 3 - int - - - maxlength - 3 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - -
-
- - - shared-content - components-header - Components Header - item - - - repoPath - /site/components/headers/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - - simpleTaxonomy - categories - Categories - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/categories.xml - undefined - - - - - shared-content - components-left-rail - Components Left Rail - item - - - repoPath - /site/components/left-rails/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - + Category Landing + + page + /page/category-landing + page-category-landing.png + false + + + + display-template + + /templates/web/pages/category-landing.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + page-nav-order + placeInNav + + Place in Nav + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + navLabel + + Nav Label + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + escapeContent + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + input + title_t + + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + node-selector + header_o + + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + false + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ Articles + + true + + + input + articles_title_t + articles + Articles Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + dropdown + category_s + articles + Category + + + + + + datasource + categories + datasource:item + + + emptyvalue + + boolean + + + readonly + + boolean + + + + + required + true + boolean + + + + + numeric-input + max_articles_i + articles + Max Articles + + 10 + + + + size + 3 + int + + + maxlength + 3 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + true + false + + + ^/site/website/(?!articles/)(.*) + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/config.xml deleted file mode 100644 index 13865b19ed..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/home
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - true - true - false - - false - page-home.png - - - ^/site/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/form-definition.xml index 4d121ee4ae..c0096586d4 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/home/form-definition.xml @@ -1,5 +1,6 @@ + -
- Home - - page - /page/home - page-home.png - false - - - - display-template - - /templates/web/pages/home.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Page Properties - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - true - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - input - navLabel - - Nav Label - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - escapeContent - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - checkbox - disabled - - Disable Page - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - title_t - core - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - header_o - core - Header - Default header is inherited from Section Defaults. Specify a new header to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-header - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - contentTypes - /component/header - contentTypes - - - tags - - string - - - - - allowDuplicates - - boolean - - - - - node-selector - left_rail_o - - Left Rail - Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. - - - - - minSize - 0 - int - - - maxSize - 1 - int - - - itemManager - components-left-rail - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - contentTypes - /component/left-rail - contentTypes - - - tags - - string - - - - - allowDuplicates - - boolean - - - - -
-
- Hero Section - - true - - - rte - hero_title_html - hero - Hero Title - - - - - - height - 410 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - uploadImages,existingImages - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - rte - hero_text_html - hero - Hero Text - - - - - - height - 200 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - existingImages,uploadImages - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - image-picker - hero_image_s - hero - Hero Image - - - - - - width - { "exact":"", "min":"", "max":"" } - range - - - height - { "exact":"", "min":"", "max":"" } - range - - - thumbnailWidth - - int - - - thumbnailHeight - - int - - - imageManager - existingImages,uploadImages - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Features - - true - - - input - features_title_t - features - Features Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - features_o - features - Features - - - - - - minSize - - int - - - maxSize - - int - - - itemManager - featuresComponents - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - contentTypes - /component/feature - contentTypes - - - tags - - string - - - - - allowDuplicates - - boolean - - - - -
-
- - - img-repository-upload - existingImages - Existing Images - image - - - repoPath - /static-assets/images/ - undefined - - - - - img-desktop-upload - uploadImages - Upload Images - image - - - repoPath - /static-assets/item/images/{yyyy}/{mm}/{dd}/ - undefined - - - - - shared-content - components-header - Components Header - item - - - repoPath - /site/components/headers/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - - shared-content - components-left-rail - Components Left Rail - item - - - repoPath - /site/components/left-rails/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - enableCreateNew - true - boolean - - - enableBrowseExisting - true - boolean - - - enableSearchExisting - true - boolean - - - - - components - featuresComponents - Features Components - item - - - allowShared - true - boolean - - - allowEmbedded - true - boolean - - - enableBrowse - true - boolean - - - enableSearch - true - boolean - - - baseRepositoryPath - /site/components - string - - - baseBrowsePath - /site/components - string - - - contentTypes - /component/feature - contentTypes - - - tags - - string - - - - + Home + + page + /page/home + page-home.png + false + + + + display-template + + /templates/web/pages/home.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + true + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + input + navLabel + + Nav Label + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + escapeContent + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + core + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + node-selector + header_o + core + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/header + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/left-rail + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ Hero Section + + true + + + rte + hero_title_html + hero + Hero Title + + + + + + height + 410 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + uploadImages,existingImages + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + rte + hero_text_html + hero + Hero Text + + + + + + height + 200 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + existingImages,uploadImages + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + image-picker + hero_image_s + hero + Hero Image + + + + + + width + { "exact":"", "min":"", "max":"" } + range + + + height + { "exact":"", "min":"", "max":"" } + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + existingImages,uploadImages + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Features + + true + + + input + features_title_t + features + Features Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + node-selector + features_o + features + Features + + + + + + minSize + + int + + + maxSize + + int + + + itemManager + featuresComponents + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/feature + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ + + img-repository-upload + existingImages + Existing Images + image + + + repoPath + /static-assets/images/ + undefined + + + + + img-desktop-upload + uploadImages + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + components + featuresComponents + Features Components + item + + + allowShared + true + boolean + + + allowEmbedded + true + boolean + + + enableBrowse + true + boolean + + + enableSearch + true + boolean + + + baseRepositoryPath + /site/components + string + + + baseBrowsePath + /site/components + string + + + contentTypes + /component/feature + contentTypes + + + tags + + string + + + + + true + false + + + ^/site/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/config.xml deleted file mode 100644 index cd3787e8b8..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/search-results
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - true - true - false - - false - page-search-results.png - - - ^/site/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/form-definition.xml index dd0471926d..5b5fa81488 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/page/search-results/form-definition.xml @@ -1,5 +1,6 @@ + -
- Search Results - - page - /page/search-results - page-search-results.png - false - - - - display-template - - /templates/web/pages/search-results.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Page - Search Results Properties - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Page - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - title_t - - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - header_o - - Header - - - - - - minSize - - int - - - maxSize - - int - - - itemManager - components-header - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - node-selector - left_rail_o - - Left Rail - - - - - - minSize - - int - - - maxSize - - int - - - itemManager - components-left-rail - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - node-selector - categories_o - - Categories - - - - - - minSize - 1 - int - - - maxSize - 1 - int - - - itemManager - categories - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- - - shared-content - components-header - Components Header - item - - - repoPath - /site/components/headers/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - - shared-content - components-left-rail - Components Left Rail - item - - - repoPath - /site/components/left-rails/ - undefined - - - browsePath - - undefined - - - type - - undefined - - - - - shared-content - categories - Categories - item - - - repoPath - /site/taxonomy - undefined - - - browsePath - /site/taxonomy - undefined - - - type - /taxonomy - undefined - - - - + Search Results + + page + /page/search-results + page-search-results.png + false + + + + display-template + + /templates/web/pages/search-results.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page - Search Results Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + node-selector + header_o + + Header + + + + + + minSize + + int + + + maxSize + + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + + + + + + minSize + + int + + + maxSize + + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + node-selector + categories_o + + Categories + + + + + + minSize + 1 + int + + + maxSize + 1 + int + + + itemManager + categories + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + + + shared-content + categories + Categories + item + + + repoPath + /site/taxonomy + undefined + + + browsePath + /site/taxonomy + undefined + + + type + /taxonomy + undefined + + + + + true + false + + + ^/site/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/config.xml deleted file mode 100644 index 33891f41f1..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/taxonomy
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - false - taxonomy.png - - - ^/site/taxonomy/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/form-definition.xml index 249d4deb59..ae074f92d2 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/content-types/taxonomy/form-definition.xml @@ -1,5 +1,6 @@ + -
- Taxonomy - - component - /taxonomy - taxonomy.png - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Taxonomy Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - repeat - items - - Items - - 1 - * - - - minOccurs - 1 - string - - - maxOccurs - * - string - - - - - input - key - - Key - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - value - - Value - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - - -
-
- + Taxonomy + + component + /taxonomy + taxonomy.png + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Taxonomy Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + repeat + items + + Items + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + input + key + + Key + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + value + + Value + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + + +
+
+ + false + false + + + ^/site/taxonomy/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/studio_version.xml b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/studio_version.xml index 1fb428280a..1adc2652d0 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/studio_version.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/1000_website_editorial/config/studio/studio_version.xml @@ -15,5 +15,5 @@ ~ along with this program. If not, see . --> - 5.0.0.1 + 5.0.0.2 diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/config.xml deleted file mode 100644 index 461a53be7e..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/company
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/items/companies/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/form-definition.xml index f98492da9c..45ad13939b 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/company/form-definition.xml @@ -1,5 +1,6 @@ + -
- Item: Company - - component - /component/company - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Item: Company Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Item - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - name_s - - Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - image-picker - logo_s - - Logo - - - - - - width - { "exact":"", "min":"50", "max":"150" } - range - - - height - { "exact":"", "min":"50", "max":"150" } - range - - - thumbnailWidth - 100 - int - - - thumbnailHeight - 100 - int - - - imageManager - upload_images,existing_images - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - rte - description_html - - Description - - - - - - height - 350 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - upload_images,existing_images - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - input - website_s - - Website - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - email_s - - Email - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - phone_s - - Phone - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - -
-
- - - img-desktop-upload - upload_images - Upload Images - image - - - repoPath - /static-assets/item/images/companies/{yyyy}/{mm}/{dd}/ - undefined - - - - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images/companies - undefined - - - - + Item: Company + + component + /component/company + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Item: Company Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Item + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + name_s + + Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + image-picker + logo_s + + Logo + + + + + + width + { "exact":"", "min":"50", "max":"150" } + range + + + height + { "exact":"", "min":"50", "max":"150" } + range + + + thumbnailWidth + 100 + int + + + thumbnailHeight + 100 + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + rte + description_html + + Description + + + + + + height + 350 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + input + website_s + + Website + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + email_s + + Email + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + phone_s + + Phone + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + +
+
+ + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/companies/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images/companies + undefined + + + + + false + true + + + /site/items/companies/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/config.xml deleted file mode 100644 index 9812cb9bc9..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/level-descriptor
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - ^/site/website/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/form-definition.xml index 76bca6ecfe..31adc30c18 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/level-descriptor/form-definition.xml @@ -1,5 +1,6 @@ + -
- Section Defaults - Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" - component - /component/level-descriptor - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Section Defaults Properties - - true - - - file-name - file-name - - File Name - - crafter-level-descriptor.level - - - - size - 100 - int - - - maxlength - 50 - int - - - readonly - true - boolean - - - - - - -
-
- + Section Defaults + Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" + component + /component/level-descriptor + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Section Defaults Properties + + true + + + file-name + file-name + + File Name + + crafter-level-descriptor.level + + + + size + 100 + int + + + maxlength + 50 + int + + + readonly + true + boolean + + + + + +
+
+ + false + true + + + ^/site/website/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/config.xml deleted file mode 100644 index 5b347b45ea..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/product
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/items/products/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/form-definition.xml index 0ec373f573..fd38469e39 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/component/product/form-definition.xml @@ -1,5 +1,6 @@ + -
- Item: Product - - component - /component/product - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Item: Product Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Item - - false - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - name_s - - Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - description_html - - Description - - - - - - height - 350 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - existing_images,upload_images - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - image-picker - image_s - - Image - - - - - - width - { "exact":"", "min":"", "max":"400" } - range - - - height - { "exact":"", "min":"", "max":"400" } - range - - - thumbnailWidth - 200 - int - - - thumbnailHeight - 200 - int - - - imageManager - upload_images,existing_images - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - checkbox-group - categories_o - - Categories - - - - - - datasource - categories - datasource:item - - - selectAll - - boolean - - - readonly - - boolean - - - - - minSize - - int - - - - - checkbox-group - tags_o - - Tags - - - - - - datasource - tags - datasource:item - - - selectAll - - boolean - - - readonly - - boolean - - - - - minSize - - int - - - - - input - price_d - - Price - Enter the price as a numerical value. - - - - - size - 12 - int - - - maxlength - 10 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - node-selector - company_o - - Company - - - - - - minSize - 1 - int - - - maxSize - 1 - int - - - itemManager - company_components - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - -
-
- - - img-desktop-upload - upload_images - Upload Images - image - - - repoPath - /static-assets/item/images/products/{yyyy}/{mm}/{dd}/ - undefined - - - - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images/products - undefined - - - - - simpleTaxonomy - categories_o - Categories - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/categories.xml - undefined - - - - - simpleTaxonomy - tags - Tags - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/tags.xml - undefined - - - - - shared-content - company_components - Company Components - item - - - repoPath - /site/items/companies - undefined - - - browsePath - /site/items/companies - undefined - - - type - /component/company - undefined - - - - + Item: Product + + component + /component/product + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Item: Product Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Item + + false + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + name_s + + Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + description_html + + Description + + + + + + height + 350 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + existing_images,upload_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + image-picker + image_s + + Image + + + + + + width + { "exact":"", "min":"", "max":"400" } + range + + + height + { "exact":"", "min":"", "max":"400" } + range + + + thumbnailWidth + 200 + int + + + thumbnailHeight + 200 + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + true + boolean + + + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories_o + datasource:item + + + selectAll + + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + + checkbox-group + tags_o + + Tags + + + + + + datasource + tags + datasource:item + + + selectAll + + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + + input + price_d + + Price + Enter the price as a numerical value. + + + + + size + 12 + int + + + maxlength + 10 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + ^[\d\.]+$ + string + + + + + node-selector + company_o + + Company + + + + + + minSize + 1 + int + + + maxSize + 1 + int + + + itemManager + company_components + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + +
+
+ + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/products/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images/products + undefined + + + + + simpleTaxonomy + categories_o + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + simpleTaxonomy + tags + Tags + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/tags.xml + undefined + + + + + shared-content + company_components + Company Components + item + + + repoPath + /site/items/companies + undefined + + + browsePath + /site/items/companies + undefined + + + type + /component/company + undefined + + + + + false + true + + + /site/items/products/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/config.xml deleted file mode 100644 index 6d735d4093..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/catalog
- simple - not-used - xml - true - true - false - - true - - - - /site/website/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/form-definition.xml index 85d80f8ee6..3216c502e9 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/page/catalog/form-definition.xml @@ -1,5 +1,6 @@ + -
- Catalog - Catalog - page - /page/catalog - undefined - false - - - - placeInNav - - true - boolean - - - display-template - - /templates/web/catalog.ftl - template - - - no-template-required - - - boolean - - - descriptor-mapper - - hierarchical-mapper - string - - - -
- Page Settings - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - path - - string - - - readonly - true - boolean - - - - - - - input - internal-name - - File Title - - - - - - size - 50 - int - - - maxlength - 60 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - int - - - - - checkbox - disabled - - Disable Catalog - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Main Content - - true - - - input - title_t - title - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - -
-
- + Catalog + Catalog + page + /page/catalog + undefined + false + + + + placeInNav + + true + boolean + + + display-template + + /templates/web/catalog.ftl + template + + + no-template-required + + + boolean + + + descriptor-mapper + + hierarchical-mapper + string + + + +
+ Page Settings + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + path + + string + + + readonly + true + boolean + + + + + + input + internal-name + + File Title + + + + + + size + 50 + int + + + maxlength + 60 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Catalog + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Main Content + + true + + + input + title_t + title + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + +
+
+ + true + true + + + /site/website/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/config.xml deleted file mode 100644 index 3dd3c26aa5..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/taxonomy
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/taxonomy/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/form-definition.xml index 284d71d701..2d503ffd82 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/content-types/taxonomy/form-definition.xml @@ -1,5 +1,6 @@ + -
- Taxonomy - - component - /taxonomy - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Taxonomy Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - repeat - items - - Items - - 1 - * - - - minOccurs - 1 - string - - - maxOccurs - * - string - - - - - input - key - - Key - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - value - - Value - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - - -
-
- + Taxonomy + + component + /taxonomy + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Taxonomy Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + repeat + items + + Items + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + input + key + + Key + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + value + + Value + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + + +
+
+ + false + true + + + ^/site/taxonomy/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/studio_version.xml b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/studio_version.xml index 1fb428280a..1adc2652d0 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/studio_version.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/2000_headless_store/config/studio/studio_version.xml @@ -15,5 +15,5 @@ ~ along with this program. If not, see . --> - 5.0.0.1 + 5.0.0.2 diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/config.xml deleted file mode 100644 index 0f11a557a8..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/config.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - -
/component/level-descriptor
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/form-definition.xml index 891daae2d6..7a6682938c 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/component/level-descriptor/form-definition.xml @@ -1,5 +1,6 @@ + -
- Section Defaults - Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" - component - /component/level-descriptor - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Section Defaults Properties - - true - - - file-name - file-name - - File Name - - crafter-level-descriptor.level - - - - size - 100 - int - - - maxlength - 50 - int - - - readonly - true - boolean - - - - - - -
-
- + Section Defaults + Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" + component + /component/level-descriptor + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Section Defaults Properties + + true + + + file-name + file-name + + File Name + + crafter-level-descriptor.level + + + + size + 100 + int + + + maxlength + 50 + int + + + readonly + true + boolean + + + + + +
+
+ + false + true diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/config.xml deleted file mode 100644 index f5e3b8753f..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/config.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - -
/page/entry
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - true - true - false - - true - image.jpg -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/form-definition.xml index 413e6eed83..70f6922318 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/content-types/page/entry/form-definition.xml @@ -1,5 +1,6 @@ + -
- A Page - A Simple Page - page - /page/entry - undefined - false - - - - display-template - - /templates/web/entry.ftl - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Page Settings - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - File Title - - - - - - size - 50 - int - - - maxlength - 60 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - page-nav-order - placeInNav - - Place in Nav - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Page - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Main Content - - true - - - input - title_t - title - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - body_html - main - Body - - - - - - height - 300 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - desktopImages - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - -
-
- - - img-desktop-upload - desktopImages - Desktop Images - image - - - repoPath - /static-assets/item/images/{yyyy}/{mm}/{dd}/ - undefined - - - - + A Page + A Simple Page + page + /page/entry + undefined + false + + + + display-template + + /templates/web/entry.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Settings + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + File Title + + + + + + size + 50 + int + + + maxlength + 60 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + page-nav-order + placeInNav + + Place in Nav + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Main Content + + true + + + input + title_t + title + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + body_html + main + Body + + + + + + height + 300 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + desktopImages + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + +
+
+ + + img-desktop-upload + desktopImages + Desktop Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + true + true diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/studio_version.xml b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/studio_version.xml index 1fb428280a..1adc2652d0 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/studio_version.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/4000_empty/config/studio/studio_version.xml @@ -15,5 +15,5 @@ ~ along with this program. If not, see . --> - 5.0.0.1 + 5.0.0.2 diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/config.xml deleted file mode 100644 index 38d021ffd4..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/author
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/items/authors/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/form-definition.xml index 951656dcb9..d376421b4c 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/author/form-definition.xml @@ -1,5 +1,6 @@ + -
- Item: Author - - component - /component/author - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Author Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Item - - false - - - - readonly - - boolean - - - - - required - - boolean - - - - - input - name_s - - Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - image-picker - photo_s - - Photo - - - - - - width - { "exact":"", "min":"50", "max":"100" } - range - - - height - { "exact":"", "min":"50", "max":"100" } - range - - - thumbnailWidth - 50 - int - - - thumbnailHeight - 50 - int - - - imageManager - upload_images,existing_images - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - input - website_s - - Website - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - biography_html - - Biography - - - - - - height - 400 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - upload_images,existing_images - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - -
-
- - - img-desktop-upload - upload_images - Upload Images - image - - - repoPath - /static-assets/item/images/avatars/{yyyy}/{mm}/{dd} - undefined - - - - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images/avatars - undefined - - - - + Item: Author + + component + /component/author + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Author Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Item + + false + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + name_s + + Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + image-picker + photo_s + + Photo + + + + + + width + { "exact":"", "min":"50", "max":"100" } + range + + + height + { "exact":"", "min":"50", "max":"100" } + range + + + thumbnailWidth + 50 + int + + + thumbnailHeight + 50 + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + true + boolean + + + + + input + website_s + + Website + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + biography_html + + Biography + + + + + + height + 400 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + +
+
+ + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/avatars/{yyyy}/{mm}/{dd} + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images/avatars + undefined + + + + + false + true + + + /site/items/authors/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/config.xml deleted file mode 100644 index 9812cb9bc9..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/level-descriptor
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - ^/site/website/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/form-definition.xml index 76bca6ecfe..31adc30c18 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/level-descriptor/form-definition.xml @@ -1,5 +1,6 @@ + -
- Section Defaults - Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" - component - /component/level-descriptor - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Section Defaults Properties - - true - - - file-name - file-name - - File Name - - crafter-level-descriptor.level - - - - size - 100 - int - - - maxlength - 50 - int - - - readonly - true - boolean - - - - - - -
-
- + Section Defaults + Section Defaults provides inherited values to all children and sibling content items. To learn more about content inheritance see craftercms.com/docs topic "Content Inheritance" + component + /component/level-descriptor + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Section Defaults Properties + + true + + + file-name + file-name + + File Name + + crafter-level-descriptor.level + + + + size + 100 + int + + + maxlength + 50 + int + + + readonly + true + boolean + + + + + +
+
+ + false + true + + + ^/site/website/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/config.xml deleted file mode 100644 index de4729acbb..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/component/post
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/items/posts/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/form-definition.xml index 7e5c731e1c..34292386ab 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/component/post/form-definition.xml @@ -1,5 +1,6 @@ + -
- Item: Post - - component - /component/post - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Post Properties - - true - - - auto-filename - file-name - - Component ID - - - - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - - - checkbox - disabled - - Disable Item - - - - - - readonly - - boolean - - - - - required - - boolean - - - - - date-time - expired_dt - - Expire Date - - - - - - showDate - true - boolean - - - showTime - true - boolean - - - showClear - false - boolean - - - showNowLink - false - boolean - - - populate - true - boolean - - - allowPastDate - true - boolean - - - populateDateExp - +1years - string - - - useCustomTimezone - false - boolean - - - readonly - - boolean - - - readonlyEdit - false - boolean - - - - - required - - boolean - - - - expired_dt_tz - - - - node-selector - authors_o - - Authors - - - - - - minSize - 1 - int - - - maxSize - - int - - - itemManager - author_components - datasource:item - - - readonly - - boolean - - - disableFlattening - - boolean - - - useSingleValueFilename - - boolean - - - - - allowDuplicates - - boolean - - - - - input - title_s - - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - image-picker - featuredImage_s - - Featured Image - - - - - - width - { "exact":"", "min":"", "max":"500" } - range - - - height - { "exact":"", "min":"", "max":"400" } - range - - - thumbnailWidth - 300 - int - - - thumbnailHeight - 200 - int - - - imageManager - uploadImage,browseImage,upload_images,existing_images - datasource:image - - - readonly - - boolean - - - - - required - - boolean - - - - - rte - body_html - - Body - - - - - - height - 300 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - upload_images,existing_images - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - - checkbox-group - categories_o - - Categories - - - - - - datasource - categories - datasource:item - - - selectAll - true - boolean - - - readonly - - boolean - - - - - minSize - - int - - - - - checkbox-group - tags_o - - Tags - - - - - - datasource - tags - datasource:item - - - selectAll - true - boolean - - - readonly - - boolean - - - - - minSize - - int - - - - -
-
- - - simpleTaxonomy - categories - Categories - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/categories.xml - undefined - - - - - shared-content - author_components - Author Components - item - - - repoPath - /site/items/authors - undefined - - - browsePath - /site/items/authors - undefined - - - type - /component/author - undefined - - - - - simpleTaxonomy - tags - Tags - item - - - dataType - [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] - undefined - - - componentPath - /site/taxonomy/tags.xml - undefined - - - - - img-desktop-upload - upload_images - Upload Images - image - - - repoPath - /static-assets/item/images/featured/{yyyy}/{mm}/{dd} - undefined - - - - - img-repository-upload - existing_images - Existing Images - image - - - repoPath - /static-assets/images/featured - undefined - - - - + Item: Post + + component + /component/post + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Post Properties + + true + + + auto-filename + file-name + + Component ID + + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Item + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + date-time + expired_dt + + Expire Date + + + + + + showDate + true + boolean + + + showTime + true + boolean + + + showClear + false + boolean + + + showNowLink + false + boolean + + + populate + true + boolean + + + allowPastDate + true + boolean + + + populateDateExp + +1years + string + + + useCustomTimezone + false + boolean + + + readonly + + boolean + + + readonlyEdit + false + boolean + + + + + required + + boolean + + + + expired_dt_tz + + + + node-selector + authors_o + + Authors + + + + + + minSize + 1 + int + + + maxSize + + int + + + itemManager + author_components + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + + + allowDuplicates + + boolean + + + + + input + title_s + + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + image-picker + featuredImage_s + + Featured Image + + + + + + width + { "exact":"", "min":"", "max":"500" } + range + + + height + { "exact":"", "min":"", "max":"400" } + range + + + thumbnailWidth + 300 + int + + + thumbnailHeight + 200 + int + + + imageManager + uploadImage,browseImage,upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + rte + body_html + + Body + + + + + + height + 300 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + + checkbox-group + tags_o + + Tags + + + + + + datasource + tags + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + +
+
+ + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + shared-content + author_components + Author Components + item + + + repoPath + /site/items/authors + undefined + + + browsePath + /site/items/authors + undefined + + + type + /component/author + undefined + + + + + simpleTaxonomy + tags + Tags + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/tags.xml + undefined + + + + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/featured/{yyyy}/{mm}/{dd} + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images/featured + undefined + + + + + false + true + + + /site/items/posts/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/config.xml deleted file mode 100644 index 337b9784ec..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/page/item-explorer
- simple - not-used - xml - true - true - false - - true - - - - /site/website/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/form-definition.xml index ecce4b7599..ac9cfe6eba 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/page/item-explorer/form-definition.xml @@ -1,5 +1,6 @@ + -
- Item Explorer - - page - /page/item-explorer - undefined - false - - - - placeInNav - - true - boolean - - - display-template - - /templates/web/item-explorer.ftl - template - - - no-template-required - - - boolean - - - descriptor-mapper - - hierarchical-mapper - string - - - -
- Page Settings - - true - - - file-name - file-name - - Page URL - - - - - - size - 50 - int - - - maxlength - 50 - int - - - path - - string - - - readonly - true - boolean - - - - - - - input - internal-name - - File Title - - - - - - size - 50 - int - - - maxlength - 60 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - int - - - - - checkbox - disabled - - Disable Item Explorer - - - - - - readonly - - boolean - - - - - required - - boolean - - - - -
-
- Main Content - - true - - - input - title_s - title - Title - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - rte - body_html - main - Help Text - - - - - - height - 350 - int - - - forceRootBlockPTag - true - boolean - - - forcePTags - true - boolean - - - forceBRTags - false - boolean - - - supportedChannels - - supportedChannels - - - rteConfiguration - generic - string - - - imageManager - - datasource:image - - - videoManager - - datasource:video - - - - - required - - boolean - - - - -
-
- + Item Explorer + + page + /page/item-explorer + undefined + false + + + + placeInNav + + true + boolean + + + display-template + + /templates/web/item-explorer.ftl + template + + + no-template-required + + + boolean + + + descriptor-mapper + + hierarchical-mapper + string + + + +
+ Page Settings + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + path + + string + + + readonly + true + boolean + + + + + + input + internal-name + + File Title + + + + + + size + 50 + int + + + maxlength + 60 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Item Explorer + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Main Content + + true + + + input + title_s + title + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + rte + body_html + main + Help Text + + + + + + height + 350 + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + + datasource:image + + + videoManager + + datasource:video + + + + + required + + boolean + + + + +
+
+ + true + true + + + /site/website/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/config.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/config.xml deleted file mode 100644 index 3dd3c26aa5..0000000000 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/config.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
/taxonomy
- simple - NOT-USED-BY-SIMPLE-FORM-ENGINE - xml - false - false - false - - true - - - - /site/taxonomy/.* - - -
diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/form-definition.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/form-definition.xml index 284d71d701..6f83b41ea5 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/form-definition.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/content-types/taxonomy/form-definition.xml @@ -1,5 +1,6 @@ + -
- Taxonomy - - component - /taxonomy - undefined - false - - - - display-template - - - template - - - no-template-required - - - boolean - - - merge-strategy - - inherit-levels - string - - - -
- Taxonomy Properties - - true - - - file-name - file-name - - Component ID - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - - - - - input - internal-name - - Internal Name - - - - - - size - 50 - int - - - maxlength - 50 - int - - - - - required - - boolean - - - - - repeat - items - - Items - - 1 - * - - - minOccurs - 1 - string - - - maxOccurs - * - string - - - - - input - key - - Key - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - input - value - - Value - - - - - - size - 50 - int - - - maxlength - 50 - int - - - readonly - - boolean - - - tokenize - false - boolean - - - - - required - - boolean - - - pattern - - string - - - - - - -
-
- + Taxonomy + + component + /taxonomy + undefined + false + + + + display-template + + + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Taxonomy Properties + + true + + + file-name + file-name + + Component ID + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + + + required + true + boolean + + + + + repeat + items + + Items + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + input + key + + Key + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + value + + Value + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + + +
+
+ + false + true + + + /site/taxonomy/.* + + diff --git a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/studio_version.xml b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/studio_version.xml index 1fb428280a..1adc2652d0 100644 --- a/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/studio_version.xml +++ b/src/main/webapp/repo-bootstrap/global/blueprints/5000_headless_blog/config/studio/studio_version.xml @@ -15,5 +15,5 @@ ~ along with this program. If not, see . --> - 5.0.0.1 + 5.0.0.2 diff --git a/src/test/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImplTest.java b/src/test/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImplTest.java index 7c70a06045..f961775344 100644 --- a/src/test/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImplTest.java +++ b/src/test/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,12 +16,14 @@ package org.craftercms.studio.impl.v2.service.content.internal; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.tuple.ImmutablePair; import org.craftercms.studio.api.v1.exception.ContentNotFoundException; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.service.site.SiteService; import org.craftercms.studio.api.v2.service.config.ConfigurationService; import org.craftercms.studio.api.v2.service.content.ContentService; +import org.craftercms.studio.model.contentType.ContentType; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; @@ -31,9 +33,13 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.test.util.ReflectionTestUtils; +import java.io.IOException; +import java.io.InputStream; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; @@ -138,4 +144,19 @@ public void getFormControllerReturnResource() throws ServiceLayerException { assertEquals(resultPair.getKey(), CONTENT_TYPE_WITH_FORM_CONTROLLER_FULL_FORM_CONTROLLER_PATH); assertEquals(resultPair.getValue(), resource); } + + @Test + public void getContentTypeTest() throws ServiceLayerException, IOException { + InputStream inputStream = new ClassPathResource("crafter/studio/content-type/" + CONTENT_TYPE + "/form-definition.xml").getInputStream(); + when(contentService.getContent(SITE_ID, CONTENT_TYPE_DEFINITION_PATH)).thenReturn(inputStream); + ContentType contentType = service.loadContentType(SITE_ID, CONTENT_TYPE); + + String expectedJson = "{\"previewable\":true,\"imageThumbnail\":\"page-test1.png\",\"noThumbnail\":false,\"quickCreate\":true," + + "\"quickCreatePath\":\"/site/website/tests/{year}/{month}\",\"type\":\"unknown\",\"pathExcludes\":[\"^/site/website/tests/excluded.*\"," + + "\"^/site/website/tests/excluded2.*\"],\"pathIncludes\":[\"^/site/website/tests/.*\"],\"id\":\"myContentType\"," + + "\"label\":\"Test Content Type\",\"allowedRoles\":[{\"name\":\"author\"},{\"name\":\"admin\"}]," + + "\"deleteDependencies\":[{\"pattern\":\"^/site/website/articles/.*\",\"removeEmptyFolder\":true}]," + + "\"copyDependencies\":[{\"pattern\":\"^/site/website/articles/.*\",\"target\":\"/site/website/articles2\"}]}"; + assertEquals(expectedJson, new ObjectMapper().writeValueAsString(contentType)); + } } diff --git a/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgraderTest.java b/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgraderTest.java new file mode 100644 index 0000000000..bd21f8d4b1 --- /dev/null +++ b/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/contentType/ContentTypeConfigMergeUpgraderTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.craftercms.studio.impl.v2.upgrade.operations.contentType; + +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.configuration2.HierarchicalConfiguration; +import org.apache.commons.io.IOUtils; +import org.craftercms.studio.api.v2.utils.StudioConfiguration; +import org.craftercms.studio.impl.v2.upgrade.StudioUpgradeContext; +import org.craftercms.studio.impl.v2.upgrade.operations.site.AbstractXsltFileUpgradeOperation; +import org.craftercms.studio.impl.v2.upgrade.operations.site.BatchXsltFileUpgradeOperation; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xmlunit.builder.DiffBuilder; +import org.xmlunit.diff.Diff; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.UUID; +import java.util.stream.Stream; + +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME; +import static org.craftercms.studio.api.v2.utils.StudioUtils.createTempFile; +import static org.craftercms.studio.api.v2.utils.StudioUtils.getStudioTemporaryFilesRoot; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class ContentTypeConfigMergeUpgraderTest { + private static final Logger logger = LoggerFactory.getLogger(ContentTypeConfigMergeUpgraderTest.class); + + @Mock + private StudioConfiguration studioConfiguration; + @Spy + @InjectMocks + private ContentTypeConfigMergeUpgrader upgrader; + + private String configFileName; + + @Before + public void setUp() throws Exception { + configFileName = UUID.randomUUID() + "config.xml"; + var config = mock(HierarchicalConfiguration.class); + when(config.getString(BatchXsltFileUpgradeOperation.CONFIG_KEY_REGEX)).thenReturn("config/studio/content-types/.+/form-definition\\.xml"); + when(config.getString(AbstractXsltFileUpgradeOperation.CONFIG_KEY_TEMPLATE)).thenReturn("crafter/studio/upgrade/5.0.x/content-type/content-type-merge-v5.0.0.2.xslt"); + when(studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME)).thenReturn(configFileName); + upgrader.init("1", "2", config); + } + + @Test + public void testUpgrade() throws Exception { + String basePath = "src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/"; + File originalFormFile = new File(basePath + "form-definition.xml"); + File originalConfigFile = new File(basePath + "config.xml"); + Path configFilePath = getStudioTemporaryFilesRoot().resolve(configFileName); + Path formFilePath = createTempFile("form-definition.xml"); + formFilePath.toFile().deleteOnExit(); + configFilePath.toFile().deleteOnExit(); + Files.copy(originalFormFile.toPath(), formFilePath, StandardCopyOption.REPLACE_EXISTING); + + Files.copy(originalConfigFile.toPath(), configFilePath, StandardCopyOption.REPLACE_EXISTING); + + File resultFile = formFilePath.toFile(); + File expectedFile = new File(basePath + "expected.xml"); + + StudioUpgradeContext context = mock(StudioUpgradeContext.class); + when(context.getTarget()).thenReturn("test-site"); + when(context.getRepositoryPath()).thenReturn(Path.of(getStudioTemporaryFilesRoot().toString())); + when(context.getFile(getStudioTemporaryFilesRoot().relativize(formFilePath).toString())).thenReturn(formFilePath); + + (doReturn(Stream.of(formFilePath)).when(upgrader)).getPaths(any()); + + upgrader.doExecute(context); + + // Assert + try (InputStream expectedIn = new FileInputStream(expectedFile); + InputStream actualIn = new FileInputStream(resultFile)) { + String expectedXml = IOUtils.toString(expectedIn, StandardCharsets.UTF_8); + String actualXml = IOUtils.toString(actualIn, StandardCharsets.UTF_8); + + // Compare the result + Diff diff = DiffBuilder + .compare(expectedXml) + .withTest(actualXml) + .ignoreWhitespace() + .ignoreComments() + .checkForSimilar() + .build(); + + if (diff.hasDifferences()) { + logger.debug(actualXml); + } + + // there should not be any differences + assertEquals(0, IterableUtils.size(diff.getDifferences()), + "The result XML should be equal to the expected XML"); + } + } +} diff --git a/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperationTest.java b/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperationTest.java index f4303cbbb2..5bdd8b2100 100644 --- a/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperationTest.java +++ b/src/test/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -64,10 +64,10 @@ public void testDefaultScript() throws IOException, UpgradeException { @Test public void testCustomScript() throws UpgradeException, IOException, URISyntaxException { - ClassPathResource inputResource = new ClassPathResource("crafter/studio/upgrade/content-type/custom/input.groovy"); + ClassPathResource inputResource = new ClassPathResource("crafter/studio/upgrade/content-type/5.0/5.0.0/custom/input.groovy"); Path inputScriptFile = createTempFile("controller.groovy", inputResource.getInputStream()); operation.updateFile(mock(StudioUpgradeContext.class), inputScriptFile); - ClassPathResource expectedResource = new ClassPathResource("crafter/studio/upgrade/content-type/custom/expected.groovy"); + ClassPathResource expectedResource = new ClassPathResource("crafter/studio/upgrade/content-type/5.0/5.0.0/custom/expected.groovy"); Assert.assertEquals("Output file does not match ", -1, Files.mismatch(inputScriptFile, Paths.get(expectedResource.getURL().toURI()))); } diff --git a/src/test/resources/crafter/studio/content-type/myContentType/form-definition.xml b/src/test/resources/crafter/studio/content-type/myContentType/form-definition.xml new file mode 100644 index 0000000000..95174f4ef1 --- /dev/null +++ b/src/test/resources/crafter/studio/content-type/myContentType/form-definition.xml @@ -0,0 +1,905 @@ + + +
+ Test Content Type + + page + myContentType + page-test1.png + true + /site/website/tests/{year}/{month} + + + display-template + + /templates/web/pages/test-page.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + core + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + node-selector + header_o + core + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + false + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/header + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/left-rail + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ Metadata + + true + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + listDirection + [{"value":"horizontal","label":"Horizonal","selected":true},{"value":"vertical","label":"Vertical","selected":false}] + dropdown + + + + + minSize + 1 + int + + + + + checkbox-group + segments_o + + Segments + + + + + + datasource + segments + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + 1 + int + + + + + checkbox + featured_b + + Featured + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + input + subject_t + subject + Subject + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + input + author_s + subject + Author + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + true + boolean + + + pattern + + string + + + + + date-time + date_dt + + Date + + + + + + showDate + true + boolean + + + showTime + + boolean + + + showClear + true + boolean + + + showNowLink + true + boolean + + + populate + true + boolean + + + allowPastDate + true + boolean + + + populateDateExp + now + string + + + useCustomTimezone + false + boolean + + + readonly + + boolean + + + readonlyEdit + false + boolean + + + + + required + true + boolean + + + + date_dt_tz + + + + textarea + summary_t + + Summary + + + + + + cols + 50 + int + + + rows + 5 + int + + + maxlength + 100000 + int + + + allowResize + true + boolean + + + readonly + + boolean + + + + + required + true + boolean + + + + + image-picker + image_s + + Image + + + + + + width + { "exact":"", "min":"", "max":"" } + range + + + height + { "exact":"", "min":"", "max":"" } + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + repeat + sections_o + article + Sections + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + rte + section_html + article + Section + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + true + boolean + + + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images + undefined + + + + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + simpleTaxonomy + segments + Segments + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/segments.xml + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + true + false + + + ^/site/website/tests/.* + + + ^/site/website/tests/excluded.* + ^/site/website/tests/excluded2.* + + + + + ^/site/website/articles/.* + true + + + + + ^/site/website/articles/.* + /site/website/articles2 + + + + author + admin + + diff --git a/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/config.xml b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/config.xml new file mode 100644 index 0000000000..713d23629f --- /dev/null +++ b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/config.xml @@ -0,0 +1,50 @@ + + + + +
/page/article
+ simple + NOT-USED-BY-SIMPLE-FORM-ENGINE + xml + true + true + true + /site/website/articles/{year}/{month} + false + page-article.png + + + ^/site/website/articles/.* + + + + + ^/site/website/articles/.* + true + + + + + ^/site/website/articles/.* + /site/website/articles2 + + + + author + admin + +
diff --git a/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/expected.xml b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/expected.xml new file mode 100644 index 0000000000..56ef1aeccc --- /dev/null +++ b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/expected.xml @@ -0,0 +1,902 @@ + + +
+ Article + + page + /page/article + page-article.png + true + /site/website/articles/{year}/{month} + + + display-template + + /templates/web/pages/article.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + core + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + node-selector + header_o + core + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + false + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/header + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/left-rail + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ Metadata + + true + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + listDirection + [{"value":"horizontal","label":"Horizonal","selected":true},{"value":"vertical","label":"Vertical","selected":false}] + dropdown + + + + + minSize + + int + + + + + checkbox-group + segments_o + + Segments + + + + + + datasource + segments + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + + checkbox + featured_b + + Featured + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + input + subject_t + subject + Subject + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + input + author_s + subject + Author + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + date-time + date_dt + + Date + + + + + + showDate + true + boolean + + + showTime + + boolean + + + showClear + true + boolean + + + showNowLink + true + boolean + + + populate + true + boolean + + + allowPastDate + true + boolean + + + populateDateExp + now + string + + + useCustomTimezone + false + boolean + + + readonly + + boolean + + + readonlyEdit + false + boolean + + + + + required + + boolean + + + + date_dt_tz + + + + textarea + summary_t + + Summary + + + + + + cols + 50 + int + + + rows + 5 + int + + + maxlength + 100000 + int + + + allowResize + true + boolean + + + readonly + + boolean + + + + + required + + boolean + + + + + image-picker + image_s + + Image + + + + + + width + { "exact":"", "min":"", "max":"" } + range + + + height + { "exact":"", "min":"", "max":"" } + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + repeat + sections_o + article + Sections + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + rte + section_html + article + Section + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + + boolean + + + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images + undefined + + + + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + simpleTaxonomy + segments + Segments + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/segments.xml + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + true + false + + + ^/site/website/articles/.* + + + + + ^/site/website/articles/.* + true + + + + + ^/site/website/articles/.* + /site/website/articles2 + + + + author + admin + +
diff --git a/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/form-definition.xml b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/form-definition.xml new file mode 100644 index 0000000000..706cfddc8a --- /dev/null +++ b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0.2/form-definition.xml @@ -0,0 +1,879 @@ + + +
+ Article + + page + /page/article + page-article.png + true + /site/website/articles/{year}/{month} + + + display-template + + /templates/web/pages/article.ftl + template + + + no-template-required + + + boolean + + + merge-strategy + + inherit-levels + string + + + +
+ Page Properties + + true + + + file-name + file-name + + Page URL + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + + + + + input + internal-name + + Internal Name + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + + + checkbox + disabled + + Disable Page + + + + + + readonly + + boolean + + + + + required + + boolean + + + + + input + title_t + core + Title + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + node-selector + header_o + core + Header + Default header is inherited from Section Defaults. Specify a new header to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-header + datasource:item + + + readonly + + boolean + + + disableFlattening + false + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/header + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + + node-selector + left_rail_o + + Left Rail + Default left-rail is inherited from Section Defaults. Specify a new left-rail to overwrite it. + + + + + minSize + 0 + int + + + maxSize + 1 + int + + + itemManager + components-left-rail + datasource:item + + + readonly + + boolean + + + disableFlattening + + boolean + + + useSingleValueFilename + + boolean + + + contentTypes + /component/left-rail + contentTypes + + + tags + + string + + + + + allowDuplicates + + boolean + + + + +
+
+ Metadata + + true + + + checkbox-group + categories_o + + Categories + + + + + + datasource + categories + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + listDirection + [{"value":"horizontal","label":"Horizonal","selected":true},{"value":"vertical","label":"Vertical","selected":false}] + dropdown + + + + + minSize + + int + + + + + checkbox-group + segments_o + + Segments + + + + + + datasource + segments + datasource:item + + + selectAll + true + boolean + + + readonly + + boolean + + + + + minSize + + int + + + + + checkbox + featured_b + + Featured + + + + + + readonly + + boolean + + + + + required + + boolean + + + + +
+
+ Content + + true + + + input + subject_t + subject + Subject + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + input + author_s + subject + Author + + + + + + size + 50 + int + + + maxlength + 50 + int + + + readonly + + boolean + + + tokenize + false + boolean + + + + + required + + boolean + + + pattern + + string + + + + + date-time + date_dt + + Date + + + + + + showDate + true + boolean + + + showTime + + boolean + + + showClear + true + boolean + + + showNowLink + true + boolean + + + populate + true + boolean + + + allowPastDate + true + boolean + + + populateDateExp + now + string + + + useCustomTimezone + false + boolean + + + readonly + + boolean + + + readonlyEdit + false + boolean + + + + + required + + boolean + + + + date_dt_tz + + + + textarea + summary_t + + Summary + + + + + + cols + 50 + int + + + rows + 5 + int + + + maxlength + 100000 + int + + + allowResize + true + boolean + + + readonly + + boolean + + + + + required + + boolean + + + + + image-picker + image_s + + Image + + + + + + width + { "exact":"", "min":"", "max":"" } + range + + + height + { "exact":"", "min":"", "max":"" } + range + + + thumbnailWidth + + int + + + thumbnailHeight + + int + + + imageManager + upload_images,existing_images + datasource:image + + + readonly + + boolean + + + + + required + + boolean + + + + + repeat + sections_o + article + Sections + + 1 + * + + + minOccurs + 1 + string + + + maxOccurs + * + string + + + + + rte + section_html + article + Section + + + + + + height + + int + + + forceRootBlockPTag + true + boolean + + + forcePTags + true + boolean + + + forceBRTags + false + boolean + + + supportedChannels + + supportedChannels + + + rteConfiguration + generic + string + + + imageManager + upload_images,existing_images + datasource:image + + + videoManager + + datasource:video + + + + + required + + boolean + + + + + + +
+
+ + + shared-content + components-header + Components Header + item + + + repoPath + /site/components/headers + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + + img-desktop-upload + upload_images + Upload Images + image + + + repoPath + /static-assets/item/images/{yyyy}/{mm}/{dd}/ + undefined + + + + + img-repository-upload + existing_images + Existing Images + image + + + repoPath + /static-assets/images + undefined + + + + + simpleTaxonomy + categories + Categories + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/categories.xml + undefined + + + + + simpleTaxonomy + segments + Segments + item + + + dataType + [{"value":"value","label":"","selected":false},{"value":"value_s","label":"String","selected":true},{"value":"value_i","label":"Integer","selected":false},{"value":"value_f","label":"Float","selected":false},{"value":"value_dt","label":"Date","selected":false},{"value":"value_html","label":"HTML","selected":false}] + undefined + + + componentPath + /site/taxonomy/segments.xml + undefined + + + + + shared-content + components-left-rail + Components Left Rail + item + + + repoPath + /site/components/left-rails/ + undefined + + + browsePath + + undefined + + + type + + undefined + + + enableCreateNew + true + boolean + + + enableBrowseExisting + true + boolean + + + enableSearchExisting + true + boolean + + + + +
diff --git a/src/test/resources/crafter/studio/upgrade/content-type/custom/expected.groovy b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0/custom/expected.groovy similarity index 100% rename from src/test/resources/crafter/studio/upgrade/content-type/custom/expected.groovy rename to src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0/custom/expected.groovy diff --git a/src/test/resources/crafter/studio/upgrade/content-type/custom/input.groovy b/src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0/custom/input.groovy similarity index 100% rename from src/test/resources/crafter/studio/upgrade/content-type/custom/input.groovy rename to src/test/resources/crafter/studio/upgrade/content-type/5.0/5.0.0/custom/input.groovy