diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index 1d4cef45d4..9bd1972ee4 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -192,7 +192,7 @@ namespace Umbraco.Core.Migrations.Upgrade To("{EE288A91-531B-4995-8179-1D62D9AA3E2E}"); To("{2AB29964-02A1-474D-BD6B-72148D2A53A2}"); - + // to 8.7.0... To("{a78e3369-8ea3-40ec-ad3f-5f76929d2b20}"); // to 8.7.0... diff --git a/src/Umbraco.Core/Models/Blocks/IBlockEditorDataHelper.cs b/src/Umbraco.Core/Models/Blocks/IBlockEditorDataHelper.cs new file mode 100644 index 0000000000..32f8431e65 --- /dev/null +++ b/src/Umbraco.Core/Models/Blocks/IBlockEditorDataHelper.cs @@ -0,0 +1,11 @@ +using Newtonsoft.Json.Linq; +using System.Collections.Generic; + +namespace Umbraco.Core.Models.Blocks +{ + public interface IBlockEditorDataHelper + { + IEnumerable GetBlockReferences(JObject layout); + bool IsEditorSpecificPropertyKey(string propertyKey); + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ac3f6bd464..eb3b487dcd 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -139,6 +139,7 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js index 4bb5f90556..2848ddaac7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js @@ -9,168 +9,6 @@ * Use the Block Editor Service to instantiate the Model Object.
* See {@link umbraco.services.blockEditorService blockEditorService} * - * ## Basic knowledge for understanding how to work with Block Editor data. - * There is a few things we need to understand before we can use the Model Object(BlockEditorModelObject). - * The data structure of a Block Editor contains two main properties 'layout' and 'data'. - * - The 'layout' property is the origin of the data, this object defines the blocks of this property including the the order and layout of those. - * - The 'data' property is the data of your blocks and is managed by the Model Object therefor it can be ignored for most use. - * - * To get a better understanding of what this means as a user of the Model Object, we need to look at some simple usages of the Model Object: - * - * ## Maintain and work with the Layout of a Block Editor. - * The 'layout' of a Block Editor can be of any structure. Therefor the Model Object(BlockEditorModelObject) cannot maintain this data. - * Since the origin of blocks is in the 'layout' the Model Object only can serve as a helper to maintain and create data. - * Therefor the Property Editor code will be using the 'layout' as origin, using the Model Object help managing speicfic parts.
- * To give an unstanding of what that means please read the following documentation of how to create a block. - * - * ## The basic setup for a Block Editor. - * ####Instantiate a Model Object and load dependencies. And provide the basic structure for the 'layout' property when reciving the reference to it: - * - *
- * 
- *     // We must get a scope that exists in all the lifetime of this data. Across variants and split-view.
- *     var scopeOfExistence = $scope;
- *     // Setup your component to require umbVariantContentEditors and use the method getScope to retrive a shared scope for multiple editors of this content.
- *     if(vm.umbVariantContentEditors && vm.umbVariantContentEditors.getScope) {
- *         scopeOfExistence = vm.umbVariantContentEditors.getScope();
- *     }
- * 
- *     // Define variables for layout and modelObject as you will be using these through our your property-editor.
- *     var layout;
- *     var modelObject;
- *     
- *     // When we are ready we can instantiate the Model Object can load the dependencies of it.
- *     vm.$onInit = function() {
- *         modelObject = blockEditorService.createModelObject(vm.model.value, vm.model.editor, vm.model.config.blocks, scopeOfExistence);
- *         modelObject.load().then(onLoaded);
- *     }
- * 
- *     function onLoaded() {
- *
- *          // Define the default layout, this is used when there is no data jet stored for this property.
- *          var defaultLayout = [];
- * 
- *          // We store a reference to layout as we have to maintain this.
- *          layout = modelObject.getLayout(defaultLayout);
- * 
- *      }
- * 
- * - * ## Create a Block. - * Use the Model Object to create a Block and append the returned layout-entry to the 'layout'. - * - * #### In the following example we will create a new block and append it at the decidered location in the 'layout' object: - * - *
- *     // continuing from previous example.
- *     
- *     // Creates a block and returns a layout entry. The layout entry is not part of layout jet as its not managed by the Model Object.
- *     var layoutEntry = modelObject.create(contentTypeKey);
- *     if (layoutEntry === null) {
- *         // The creation was not successful, therefore exit and without appending anything to our 'layout' object.
- *         return false;
- *     }
- * 
- *     // If we reach this line, we are good to add the layoutEntry to layout model.
- *     // In this example our layout is an array and we would like to append the new block as the last entry.
- *     layout.push(layoutEntry);
- *     
- * 
- * - * ## Working with Blocks - * - * The layout-entries does not provide much value when it comes to displaying or editing Blocks. - * Our Model Object provides the option to get a Block Object for a given Block. Retrived by parsing the layout-entry of the block we would like. - * The Block Object provides data of interest, the most important of these properties are: Block configuration, A label and the Block content in the Element Type Data Model format, this Content-model is very usefull to make UI for editing the Content of a Block. - * - * #### This example uses the Model Object to retrive a Block Object for outputting its label in the console.
- * - *
- *     // We store blocks in the layout
- *     var layout = modelObject.getLayout([]);
- * 
- *     if (layout.length > 0) {
- * 
- *         // Get first entry of from the layout, which is an array in this sample.
- *         var firstLayoutEntry = layout[0];
- * 
- *         // Create a Block Object for that entry.
- *         var block = modelObject.getBlockObject(firstLayoutEntry);
- * 
- *         // Check if the Block Object creation went well. (If a block isnt supported by the configuration of the Property Editor)
- *         if(block !== null) {
- *             console.log(block.label);
- *         }
- * 
- *     }
- * 
- * - * #### This similar example uses the Block Object for settings a value on the first property in the Blocks Content.
- * - *
- *     // We store blocks in the layout
- *     var layout = modelObject.getLayout([]);
- * 
- *     if (layout.length > 0) {
- * 
- *         // Get first entry of from the layout, which is an array in this sample.
- *         var firstLayoutEntry = layout[0];
- * 
- *         // Create a Block Object for that entry.
- *         var block = modelObject.getBlockObject(firstLayoutEntry);
- * 
- *         // Check if the Block Object creation went well. (If a block isnt supported by the configuration of the Property Editor)
- *         if(block !== null) {
- *             block.content.variants[0].tabs[0].properties[0].value = "Hello world";// This value will automaticly be synced to the Property Editors Data Model.
- *         }
- * 
- *     }
- * 
- * - * See {@link umbraco.services.blockEditorModelObject#methods_getBlockObject getBlockObject} method for more information on the properties avaiable on a Block Object. - * - * ## Remove a Block - * - * Removing a Block and destroying the data of it is done by calling one method of the Model Object, but we have remember that we need to maintain the 'layout' object and this case is a great example of how thats done. - * You will find that your code will very much be based on working with Block Objects and therefor removal of a Block is be done by refering a Block Object. - * - * #### This example shows how to remove the first Block of our imaginary Block Editor and removing the block from our layout. - * - *
- *     var layout = modelObject.getLayout([]);
- *     if (layout.length > 0) {
- * 
- *         // Get first entry of from the layout, which is an array in this sample.
- *         var firstLayoutEntry = layout[0];
- * 
- *         // Create a Block Object for that entry.
- *         var block = modelObject.getBlockObject(firstLayoutEntry);
- * 
- *         // Check if the Block Object creation went well. (If a block isnt supported by the configuration of the Property Editor)
- *         if(block !== null) {
- *             modelObject.removeDataAndDestroyModel(block);// Removing the data of our block and destroying the Block Object for performance reasons.
- *             
- *             // We need to maintain the 'layout' object, so therefor its up to our code to remove the block from the 'layout' object.
- *             const index = array.indexOf(5);
- *             if (index > -1) {
- *                 layout.splice(index, 1);
- *             }
- *         }
- * 
- *     }
- *
- * 
- * - * - * ## Manage a Render Model for Displaying Blocks in the Property Editor - * - * For Rendering a Block in our AngularJS view - * - *
- *     // TODO to be done.
- * 
- * - * */ (function () { 'use strict'; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umbBlockCard.component.js b/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umbBlockCard.component.js index 876d663e09..41ae035617 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umbBlockCard.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umbBlockCard.component.js @@ -1,8 +1,6 @@ (function () { "use strict"; - // TODO: Does this belong in the property editors folder? - angular .module("umbraco") .component("umbBlockCard", { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/elementeditor/umb-element-editor-content.component.html b/src/Umbraco.Web.UI.Client/src/views/components/elementeditor/umb-element-editor-content.component.html index fea0880195..0c6ccbd22f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/elementeditor/umb-element-editor-content.component.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/elementeditor/umb-element-editor-content.component.html @@ -9,17 +9,18 @@
- - + show-inherit="vm.model.variants.length > 1 && !property.culture && !activeVariant.language.isDefault" + inherits-from="defaultVariant.language.name">
- +
@@ -28,8 +29,9 @@
- + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.controller.js index c439d89911..dd9fc7f83d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.controller.js @@ -97,8 +97,8 @@ vm.openAddDialog = function ($event, entry) { - //we have to add the 'alias' property to the objects, to make the data match the requirements of itempicker. - var selectedItems = _.each(Utilities.copy($scope.model.value), function (obj) { + //we have to add the 'alias' property to the objects, to meet the data requirements of itempicker. + var selectedItems = Utilities.copy($scope.model.value).forEach((obj) => { obj.alias = vm.getElementTypeByKey(obj.contentTypeKey).alias; return obj; }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.html index d192bc0900..4f60b5d567 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-property-editor.html @@ -8,11 +8,13 @@
- @@ -63,12 +65,14 @@
- @@ -87,11 +91,12 @@ - + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-scoped-block.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-scoped-block.component.js index e26fb58fd6..314ce1fcaa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-scoped-block.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umb-block-list-scoped-block.component.js @@ -19,7 +19,7 @@ stylesheet: "@", view: "@", block: "=", - api: "=", // Should this be a one way bind? + api: "<", index: "<" } } @@ -27,7 +27,7 @@ function BlockListScopedBlockController($compile, $element, $scope) { var model = this; - model.$onInit = function () { + model.$onInit = function() { // Ugh, due to the way we work with angularjs and property editors not being components and needing to use ng-include, // it means we need to expose things directly on the $scope so they can use them. diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umbBlockListPropertyEditor.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umbBlockListPropertyEditor.component.js index ec45df3d6c..6ced8cf2db 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umbBlockListPropertyEditor.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/blocklist/umbBlockListPropertyEditor.component.js @@ -63,6 +63,10 @@ labels.content_createEmpty = data[1]; }); + + + + vm.$onInit = function() { inlineEditing = vm.model.config.useInlineEditingAsDefault; @@ -131,8 +135,8 @@ // Append the blockObjects to our layout. vm.layout.forEach(entry => { - if (entry.$block === undefined || entry.$block === null) { - + // $block must have the data property to be a valid BlockObject, if not its concidered as a destroyed blockObject. + if (entry.$block === undefined || entry.$block === null || entry.$block.data === undefined) { var block = getBlockObject(entry); // If this entry was not supported by our property-editor it would return 'null'. diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 6939e5bbe6..7df379aa81 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1819,4 +1819,36 @@ Mange hilsner fra Umbraco robotten Åben egenskabshandlinger + + Opret ny blok + Tilføj en indstillings afsnit + Tilføj visning + Tilføj stylesheet + Vælg billede + Opret ny + Overskriv stylesheet + Tilføj stylesheet + Redigerings udseende + Data modeller + katalog udseende + Baggrunds farve + Ikon farve + Indholds model + Label + Speciel visning + Indstillings model + Rederings lagets størrelse + Tilføj speciel visning + Tilføj instillinger + Overskriv label form + %0%.]]> + Indhold der benytter sig af denne blok vil gå bort. + + Billede + Tilføj billede + Opret ny + Udklipsholder + Indstillinger + + diff --git a/src/Umbraco.Web.UI/Views/Partials/BlockList/Default.cshtml b/src/Umbraco.Web.UI/Views/Partials/BlockList/Default.cshtml index 22fd4283de..8e5de940c5 100644 --- a/src/Umbraco.Web.UI/Views/Partials/BlockList/Default.cshtml +++ b/src/Umbraco.Web.UI/Views/Partials/BlockList/Default.cshtml @@ -10,7 +10,7 @@ var data = layout.Data; try { - @Html.Partial("BlockList/Components/" + data.ContentType.Alias, (data, layout.Settings)) + @Html.Partial("BlockList/Components/" + data.ContentType.Alias, layout) } catch (Exception ex) {