Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Henrik Vincent 122 posts 616 karma points
    Mar 13, 2019 @ 10:33
    Henrik Vincent
    0

    Rendering custom property editor in v8

    Hi guys

    I'm trying to get my v7 custom property editor to work in v8, but having some problems.

    My v7 view looks like this:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage
    @{
    
    var robots = CurrentPage.metaRobots;
    var meta = CurrentPage.seoMeta;
    
    <meta name="robots" content="@robots.robots" />
    
        <title>@meta.title</title>
        <meta name="description" content="@meta.description" />
    }
    

    I know CurrentPage isn't in v8 anymore, so tried changing it to Model.Value("metaRobots") and Model.Value("seoMeta")

    @inherits Umbraco.Web.Mvc.UmbracoViewPage 
    @{
    var robots = Model.Value("metaRobots");
    var meta = Model.Value("metaPreview");
    
    <meta name="robots" content='@robots.robots' />
        <title>@meta.title</title>
        <meta name="description" content="@meta.description" />
    }
    

    But I get this error:

    CS1061: 'object' does not contain a definition for 'robots'

    Can anyone point me in the right direction of how I render this property editor in my view?

    Best

    Henrik

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Mar 13, 2019 @ 10:46
    Søren Gregersen
    1
    var robots = Model.Value<YourOwnRobotsObj>("metaRobots");
    

    And then you need a PropertyValueConverter.

    Otherwise, use Value<string>("meatRobots") and parse the json with JsonConvert in the Newtonsoft.Json package (already in umbraco).

  • Henrik Vincent 122 posts 616 karma points
    Mar 13, 2019 @ 11:58
    Henrik Vincent
    0

    Thanks Søren

    Is <YourOwnRobotsObj> the name of my datatype or the Property Editor Alias?

    Henrik

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Mar 13, 2019 @ 12:21
    Søren Gregersen
    0

    that is a model that represents the data your editor saves :)

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Mar 13, 2019 @ 11:49
    Frans de Jong
    0

    To complete this answer here's a link to the documentation on Property value converters: https://our.umbraco.com/Documentation/Extending/Property-Editors/value-converters

  • Henrik Vincent 122 posts 616 karma points
    Mar 13, 2019 @ 11:56
    Henrik Vincent
    0

    Thanks to the both of you.

    I've never heard of PropertyValueConverters up until now, nor have I used the Newtonsoft.Json package before, so I'm kinda lost on how to get further with this.

    This is my controller:

    angular.module("umbraco")
        .controller("MetaRobotsController",
        function ($scope) {
    
    
            $scope.noindex = $scope.model.value.noindex;
            $scope.nofollow = $scope.model.value.nofollow;
    
            $scope.$watch("noindex", function () {
                $scope.UpdateModel();
            });
    
            $scope.$watch("nofollow", function () {
                $scope.UpdateModel();
            });
    
            $scope.UpdateModel = function () {
                var r1 = "index";
                var r2 = "follow";
                var robots = "";
                if ($scope.noindex == true || $scope.nofollow == true) {
                    r1 = $scope.noindex == true ? "noindex" : "index";
                    r2 = $scope.nofollow == true ? "nofollow" : "follow";
                }
                $scope.robots = [r1,r2].join();
    
                $scope.model.value = {
                    noindex: $scope.noindex, 
                    nofollow: $scope.nofollow, 
                    robots: $scope.robots
                };
            };
        });
    

    And this my view:

    <div ng-controller="MetaRobotsController">
        <div class="robots control-group umb-control-group">
            <label class="control-label ng-binding">Robots 🤖</label>
            <div class="checkWrap">
                <p>Index</p>
                <input type="checkbox" ng-model="noindex" id="noindex" class="robotsCB">
                <label for="noindex">NOINDEX</label>
                <p>Noindex</p>
            </div>
            <div class="checkWrap">
                <p>Follow</p>
                <input type="checkbox" ng-model="nofollow" id="nofollow" class="robotsCB">
                <label for="nofollow">NOFOLLOW</label>
                <p>Nofollow</p>
            </div>
        </div>
        <div class="robotsPreview control-group umb-control-group">
            <div class="previewWrap">
                <label class="control-label ng-binding">Robots preview</label>
                <code>
                &lt;meta name=&quot;robots&quot; content=&quot;<span>{{robots}}</span>&quot; /&gt;
                </code>
            </div>
        </div>
    </div>
    

    Which of the solutions, would you suggest me to go with, with this setup.

    Hope you can give me the last push in the right direction :)

    Best

    Henrik

  • Bo Jacobsen 596 posts 2393 karma points
    Jun 19, 2019 @ 09:26
    Bo Jacobsen
    0

    Hi Henrik.

    Its a bit confusing because Umbraco havent updated the documentation for Umbraco 8 at https://our.umbraco.com/Documentation/Extending/Property-Editors/value-converters and i am still trying myself to figure the new way out

    Umbraco 7 worked this way.

    using Newtonsoft.Json;
    using Umbraco.Core.Models.PublishedContent;
    using Umbraco.Core.PropertyEditors;
    
    public class CustomProperty
    {
        [JsonProperty("noindex")]
        public bool NoIndex { get; set; }
    
        [JsonProperty("nofollow")]
        public bool NoFollow { get; set; }
    
        [JsonProperty("robots")]
        public string Robots { get; set; }
    }
    
    
    public class CustomPropertyConverter : IPropertyValueConverter
    {
        public object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
        {
            return source;
        }
    
        public object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
        {
            try
            {
                return JsonConvert.DeserializeObject<CustomProperty>(source as string);
            }
            catch
            {
                return null;
            }
        }
    
        public object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
        {
            return null;
        }
    
        public bool IsConverter(PublishedPropertyType propertyType)
        {
            return propertyType.PropertyEditorAlias.Equals("Same.Alias.As.From.Package.Manifest");
        }
    }
    

    The Umbraco 8 way, Maybe this link can help you further https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.PropertyEditors.IPropertyValueConverter.html

    public class CustomPropertyConverter : IPropertyValueConverter
    {
        public object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
        {
            throw new NotImplementedException();
        }
    
        public object ConvertIntermediateToXPath(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
        {
            throw new NotImplementedException();
        }
    
        public object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
        {
            throw new NotImplementedException();
        }
    
        public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
        {
            throw new NotImplementedException();
        }
    
        public Type GetPropertyValueType(PublishedPropertyType propertyType)
        {
            throw new NotImplementedException();
        }
    
        public bool IsConverter(PublishedPropertyType propertyType)
        {
            throw new NotImplementedException();
        }
    
        public bool? IsValue(object value, PropertyValueLevel level)
        {
            throw new NotImplementedException();
        }
    }
    
  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jun 19, 2019 @ 09:29
    Frans de Jong
    2

    Here's one I made for a simple string propertytype:

    Should be self explanatory? Otherwise please ask ;)

      using System;
    using Umbraco.Core.Models.PublishedContent;
    using Umbraco.Core.PropertyEditors;
    
    namespace Extensions.ValueConverters
    {
        public class FontawesomeDropdownPropertyConverter : PropertyValueConverterBase
        {
            public override bool IsConverter(PublishedPropertyType propertyType) => propertyType.EditorAlias.Equals("FontAwesomeIconsDD");
    
            public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
                => PropertyCacheLevel.Snapshot;
    
            public override Type GetPropertyValueType(PublishedPropertyType propertyType)
                => typeof(string);
    
            public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
            {
                string sourceString = source?.ToString();
                return sourceString;
            }
    
            public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
            {
                // source should come from ConvertSource and be a string (or null) already
                return inter ?? string.Empty;
            }
            public override object ConvertIntermediateToXPath(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
            {
                return inter;
            }
        }
    }
    
  • Bo Jacobsen 596 posts 2393 karma points
    Jun 21, 2019 @ 11:55
    Bo Jacobsen
    0

    I can verify that Frans solution works. I just created my own from his example.

    So instead of inherit from the interface IPropertyValueConverter you inherit from the abstract class PropertyValueConverterBase and only override what you need.

Please Sign in or register to post replies

Write your reply to:

Draft