So when I say I work with Umbraco, people kind of always go, "ahh Umbongo Umbongo, they drink it in the Congo" referencing the TV advert jingle for sugar and fruit flavoured drink 'Umbongo' from the mid-nineteen eighties; which I can't deny is a particulary catchy jingle, but one I've always felt slightly self-concious singing along to. On the other hand, the Kia-Ora jingle of the same vintage and ouvre is as catchy as a rash, and I'm much more comfortable with it in the sing-a-long stakes. So when I had to name my blog which would largely concern Umbraco subject matter and I HAD to pick an eighties fruit based tv advert to reference, I chose the Kia-Ora one. Now I could have gone with the ad strapline 'We all adore a Umbraco' but somehow 'Umbraco, too orangey for crows' made more sense (nonsense). So sorry for wasting your time with this explaination, but I think it gives a fairly good indication about whether it's worth reading any of the blog posts...

Bad Spaces

Written by @marcemarc on Monday, 29 February 2016

So the Tiny MCE Rich Text Editor has been adding a lot of extra <p></p> tags and <p>&nbsp;</p> in Umbraco recently; Bad spaces - particularly when inserting Macros it seems.

In the past I've played with the Tiny MCE config, and used the 'forced_root_block' setting and that has prevented them from being added: see an article here on how to do that:

http://scottsdevblog.com/2011/08/get-rid-of-those-pesky-p-tags-in-umbracos-tinymce-editor/

but somehow, on this last project I was working on - I couldn't get it to work like it used to :-( let me know if it still works right ? (probably just caching or something)

Anyway I didn't have time to mess around, tweaking and hoping and F5ving; and so instead, I hooked into the ContentService's saving event, checked for my rich text editor property (with alias 'content'), and used a Regex to strip out any empty paragraphs:

void ContentService_Saving(IContentService sender, Umbraco.Core.Events.SaveEventArgs e)
{
   foreach (var content in e.SavedEntities)
   {
      if (content.HasProperty("content"))
      {
         var contentHtml = content.GetValue("content");
         if (contentHtml != null)
 { // remove empty paragraphs var removeBlankParasRegex = @"<p[^>]*>(\s| |)*"; var strippedHtml = Regex.Replace(contentHtml.ToString(), removeBlankParasRegex, ""); // remove empty paragraphs with a non breaking space content.SetValue("content",strippedHtml);

} } } }

The nice thing about this approach is the editors get immediate feedback when they save, that the rogue spacing has been removed before they publish.

Whereas if you are relying on:

@Umbraco.Field("propertyAlias", removeParagraphTags:true)

then it will still look a bit messy in the back office.

To register the saving event, create a class that inherits ApplicationEventHandler, and override ApplicationStarting to hook up to the saving event:

public class ApplicationStartUp : ApplicationEventHandler
{
   protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
   {
      ContentService.Saving += ContentService_Saving;
   }
}

Custom Macro Parameter Types Editor Odyssey

Written by @marcemarc on Tuesday, 16 February 2016

Hey this may not be obvious but creating Custom Macro Parameter Type's in Umbraco 7 has gotten insanely easy, without anyone really shouting about it. (or if they did I wasn't listening properly, I do apologise - I bet there's something on Tim Geyssens' excellent nibble.be blog about it - but in fact if you wondered about this and looked in the official docs:

https://our.umbraco.org/documentation/Extending/Macro-Parameter-Editors/

it says:

"If you want to create a new macro parameter editor you will need some c# programming and database knowledge:

First create a class deriving from a webcontrol and implement the IMacroGuiRendering interface. Afterwards, open your database editor. Find the cmsMacroPropertyType table and add the a new property editor."

Boo, that sucks! and it's also not true anymore!

Because now in the wonderful world of Umbraco 7 and angularJS - if you can create an Umbraco Property Editor, you can create a custom Macro Parameter Type Editor too!

The secret (shsssshhh) is to create an angularJS property editor, as you normally would, then in the package.manifest file; add the property:

isParameterEditor and set it to true.

that's it.

Not only will your editor appear in the list of property editors, it will now be available as a Macro Parameter Type too !!

undefined

Example, (always you want an example).

Well in the real world, I often have to build Umbraco sites where editors insert images into a Rich Text Area. (as not everyone is weaned onto using the grid yet). Now you might want that inserted image to have very specific markup ie class="responsive-image", and have a caption underneath, or use the new html5 picture element that all the cool kids are talking about instead of the img tag.

So this could lead you to abandoning the Insert Media button and creating a macro instead to insert the image into the rich text editor, you can specify a parameter of media picker type; and then be very specific about the markup that gets written out for the picked image.

undefinedWhich is all great and that but,... then the editor wants to align the image right or left amongst their text. Well you can create another parameter which is a textbox and have them type L or R into it or maybe create another Macro called 'Insert Image Right' to add the floating markup but it doesn't feel awesome. What you really want to provide is a nice radio button list to infer the options for positioning the image.

The default Macro Parameter Types are a bit lacking when it comes to this kind of thing.

So let's create a custom 'ImagePosition' Macro Parameter Type editor, to provide radio button options of how to position the inserted image, that we can then read in our macro implementation to apply relevent markup / css classes etc.

This is what our package.manifest file looks like:

{
 "$schema": "/App_Plugins/manifestSchema.json",
 "propertyEditors": [ 
 {
 "alias": "tooorangey.ImagePosition",
"name": "Image Position",
 "isParameterEditor": true,
 "editor": {
 "view": "~/App_Plugins/tooorangey.ImagePosition/ImagePosition.html",
 "valueType": "STRING"
}}],
 "javascript": [
"~/App_Plugins/tooorangey.ImagePosition/ImagePosition.controller.js"
 ]
}

Our View:

<div ng-controller="tooorangey.ImagePositionController">

<div class="radio" ng-repeat="position in positions" id="selectstatus-{{position.Name}}">
 <label>
 <input type="radio" name="position" ng-change="handleRadioClick()"
 ng-model="model.value" value="{{position.Name}}">{{position.Name}}
</label>
 </div>
 </div>

Our Controller:

(I'm hardcoding the options here, there isn't the concept of prevalues for Macro Type Parameter Property Editors, but you could read the values in from an API endpoint etc

angular.module("umbraco").controller("tooorangey.ImagePositionController", function ($scope) {

 if ($scope.model.value == null) {
    $scope.model.value = 'FullWidth';
}

$scope.positions = [
    {
    Name: 'FullWidth'
   },
    {
    Name: 'Left'
    },
    {
  Name: 'Right'
   },
   {
   Name: 'Center'
   } 
];

 $scope.handleRadioClick = function (status) {
 // alert($scope.model.value); 
 };
});,

we can then read the parameter in our macro using:

var imagePosition = Model.GetParameterValue<string>("parameterAlias");

and depending on this value align our images appropriately.

In conclusion it does kind of mean you can kind of go to town on creating custom Macro Parameter Types to make the editing experience more delightful or at least be aware it's easy to re-use existing property editors on macros parameter types.


Moving, Just keep moving... or how to move your properties when you've mucked up your compositions and doc types

Written by @marcemarc on Wednesday, 10 February 2016

Ok so the scenario here is you've created a Document Type, let's say for a News Article, and you've used Compositions to compose your Document Types,
because you have lots different types of pages with lots of common properties between them.

However your News Articles need to be tagged and you have two different 'tagging' properties that are only used on News Articles, and because they are only used on a News Article, you've created them as properties on the News Article document type itself, rather than an actual 'Tagging Composition'.

All's well, the tagging isn't used anywhere else.

But then suddenly in your agile iterations it becomes clear that there needs to be a 'Video News Article' Document Type for a different kind of
Article, with all the same properties as a News Article but with some extra ones for videos and that.

The Video News Article needs the same tagging properties as the News Article - Nested Document Type Veterans know that you can surely just create your new
Video News Aricle, underneath your News Article, it will inherit all the properties of the News Article, and enable to add your additional Video
properties, along with a suitable video icon - job done.

However in the brave new world of Compositions, this will lock the structure of the News Article document type, and you'll get the message, this content
type is used as a parent and/or in a composition and therefore cannot be composed itself...

undefined 

or for those of you following along in the lovely new 7.4 UI:

 undefinedundefined

What does that actually mean ? well it means you can't add or remove any compositions in the future from the News Article document type - but it's not unreasonable in this scenario to think you might want to update the News Article again, I mean the client has just invented the need for a Video News Article what else will change ?

So what are the options...

Well you might also think you could just create a new composition, create the tagging properties on that, and add that composition to your two article document types; however these will be new 'different' properties with different ids, and you will lose any data on the existing news article tagging properties that have already been entered.

I think maybe what the message is trying to suggest is that you should now treat the News Article document type as a composition, and create a further new News Article doc type underneath, and migrate all of your existing content from the old News Article to the new one; but it's not a quick fix.

Finally your other more obvious solution is to duplicate the properties on both the News Article and the Video News Article, and it will be fine, but as a developer it
will nag away at you for the rest of your caffeine fueled development days, and when people say the project went well, and the client says they are really
happy with what you've done, you will not be able to enjoy this feedback, because in your heart you know the solution is fundamentally flawed, broken and makes you sad to think of it.

If only there was a way to move the properties from the Document Type to a Composition, without losing the data...

... ok not saying try this at home or anything but.

In the Umbraco database (stop reading now, he's talking about hacking the Umbraco database directly, he's gone mad) the data is stored against the Property
Id, and that Property appears on a particular document type because it is mapped to a ContentTypeId (the doctype) and to a PropertyTypeGroupId (the tab on
the doctype) sooooooooooooo

In the Umbraco Back Office create a new Composition, say _taggingcomposition. Add a tab called 'Tagging' - and update your News Article and Video News
Article to use that composition.

Now connect to your Umbraco Sql Server Db and run the following:

SELECT TOP 1000 [id]
,[parentGroupId]
,[contenttypeNodeId]
,[text]
,[sortorder]
FROM [atgmedia].[dbo].[cmsPropertyTypeGroup]

find your new composition and tab, (it will be the last one), and make a note of the Id and the ContentTypeNodeId for your new composition / tab
combination.

let's say ContentTypeNodeId is 1234
and Id = 66

Find the Id of the property you want to move, using it's alias:

SELECT TOP 1000 [id]
,[dataTypeId]
,[contentTypeId]
,[propertyTypeGroupId]
,[Alias]
,[Name]
,[sortOrder]
,[mandatory]
,[validationRegExp]
,[Description]
,[UniqueID]
FROM [atgmedia].[dbo].[cmsPropertyType]
where alias = 'aliasOfYourProperty'

Let's say the Id is 111

Now Update the properties entry in the cmsPropertyType table to use the new ContentTypeId and PropeTypeGroupId for your new composition:

Update cmsPropertyType
SET contentTypeId = 1234, propertyTypeGroupId = 66
Where id =111

(substituting your values of course)

But nothings happened!

So properties and where they appear are all cached, so we need to trigger the application to restart for Umbraco to become aware that the properties have
moved.

So break the web.config or recycle the app pool etc

And now the tagging properties should appear on the Composition, and in turn appear on both the News Article and the News Video Article; and because the ids
of the underlying properties 'haven't changed' they've never really left the News Article document type, all the tagging data values entered so far
on News Articles remain intact.

So you're all ready for next week's 'Sound Clip Article' right?

... and I'm not saying you're healed and free to bask in the feedback on the project from the client, because even though the situation is resolved,
let's face it, you're still really annoyed and jaded with yourself for not foreseeing this requirement in the first place!


Evolution of the grid

Written by @marcemarc on Monday, 20 April 2015

I've been looking at the new Grid Layout approach in Umbraco 7, and have been trying to get my head around how the grid editor you configure in the backoffice => maps => to the kind of responsive grid html you might put together for a these days website.

The mapping mismatch is that out-of-the-box you have a 'responsive' framework 'bootstrap3.cshtml' or 'bootstrap2.cshtml' - partial razor file to get you started, that is wired to work with the GetGridHtml umbraco helper method, that magically writes out the content the editor has entered into the grid (and you can overload it with the 'framework' partial view of your choice - I have created one for foundation5 for use with this blog - [Insert responsive framework debate here]),

I digress,

so 'out-of-the-box' the starter 'framework' razor examples will just write out col-md-4, for your chosen cell of '4' column width; but in reality you are probably also going to want to write out further classes to control how the cell responds to being laid out on different screen sizes, ie you may want your col-md-4 to be col-xs-6 on a smaller display screen, or col-lg-8 on a larger display, or push or pull or offset or whatever.

It would be easy to dismiss or misunderstand the grid's viability, based on this mismatch - but there are workarounds, and it's early days for the grid, and it's a bit like shooting the first evolved land mammal in the foot on the grounds that it could not type.

So anyways workarounds -

you can customize your responsive framework razor file to handle your crazy overriding of the responsive grid layout, how you do this depends a little on who is going to be editing the site, and what their level of understanding of responsive grids. Traditionally it's designers who would perhaps understand and control where the site design decides to respond in a grid, but the lines blur when it comes to content delivery...

1) Non Grid Aware Editors - you will probably want to create custom grid row's with meaningful names eg. 'Product Row' or 'Featured Articles' and then in your framework partial view, check for the name of the row and write your own custom implementation of the grid classes.eg

@foreach (var row in s.rows) {
if (row.Name == "Product Row"){
@doCrazyProductRowRendering(row);
}
else {
//default row render
@renderRow(row, false);
}
}

The editor need not know where and how the content breaks, but broadly get the notion of the grid organising the content. There is no row 'alias' so you need to target the row 'name' used on the particular project.

2) Grid Aware-ish Editors - crying out for an alternative to the rich text editor, you can perhaps call your columns more griddy names '4 col row' etc although that soon becomes '4 col 3 on ipad portrait row'...

... You can create 'custom config settings' for editors to apply to 'cells' or to 'rows', just by adding a bit of json config to your grid data type, you could add a 'row type' radiobutton list, and use these values in the framework razor partial to customize the row rendering.

undefined

undefined

undefined

You get a blob of json representing the grid content, and you can see here the 'config' settings that you have configured, to be added, and the value chosen by the editor.

undefined

3) Super Grid Aware Editors - They can just apply the relevant grid css class names to the grid cell or row via the settings button, but every time they add content they'd need to remember to apply them, imagine the flexibility...

undefined

So why does all this feel a bit fiddly at the moment? - Umbraco isn't trying to tie you to using bootstrap, and there isn't a common vocabulary to say things like '4 column layout that collapses to 2 on an iPad Portrait view, but 1 column on smaller devices' - the grid class names are the language, and each responsive grid has different class names and techniques, and so presenting these in the back office coherently would be a bit difficult.

With the 'Custom Config Settings' they have added a degree of flexibility to allow you to extend the interface to give editors additional input to each row and cell which could be used to determine how they are rendered, but I think it would be nice to have the option to do this at the data type configuration stage -  'out of plain site' of the editors, ie when you configure the columns for a row, it would be good to be able to set some default css classes here or other maybe other settings.

undefined

So if you created a "Product Row" of 4 - 4 - 4 when you set the value 4, in the grid data type editor, you could also add 'col-xs-6' then whenever this row is rendered in the framework file it's custom css class could be written out, along with additional editor added classes.

In the scenario that the designer still decides the points at which the design should respond, the site implementers could add the relevant classes here, and not have to customize the framework razor file, and editors wouldn't need to know the grid classes, or wouldn't need to remember to apply them on every row, on every page.

UPDATE: I created an accompanying Issue / feature request - http://issues.umbraco.org/issue/U4-6585 and tentative fix: https://github.com/umbraco/Umbraco-CMS/pull/678

undefined

 


It's not that simple, this dictionary, never has a word for the way I'm feeling

Written by @marcemarc on Monday, 13 April 2015

Ok so you upgrade your client's website to Umbraco 7 - their multilingual editors in Umbraco 6 didn't have access to 'settings' and the 'dictionary' - even if you relocated it to the translation section (where is should be by default) - but you worked around this by installing Dictionary Dashboard package coupled with 'my Dictionary Search thing' (see: http://tooorangey.co.uk/posts/yes-i-see-how-it-works-but-what-is-the-dictionary-item-called-that-i-need-to-edit/)

- but now with the upgraded site, you announced to the client, that one of the upgrade benefits is the dictionary section of Umbraco can now be moved into the 'translation section' (http://issues.umbraco.org/issue/U4-5413), which you do for them, but they've kind of forgotten what the dictionary section looks like, as they have been accustomed to the workaround, and they 'don't like' the new way of changing dictionary items in Umbraco 7, the editors want to be able to search for the translated text rather than know the dictionary key, and since there is no Dictionary Dashboard package for Umbraco 7 and my search thing was a User Control, you hastily cobble together this:

uDictionaryItemSearch

undefined

undefined

undefined

Which should allow editors to search by dictionary key or by the translated text, and then link to the settings section, or edit the text, there and then.

It's on github here: https://github.com/marcemarc/tooorangey.DictionaryItemKeySearch

Our Umbraco: https://our.umbraco.org/projects/backoffice-extensions/udictionaryitemsearch

Nuget: Install-Package tooorangey.uDictionaryItemSearch


Yes, I see how it works, but what is the Dictionary Item called that I need to edit ?

Written by @marcemarc on Wednesday, 29 October 2014

The Dictionary section of Umbraco is a place to create, well, dictionary items, you create this 'Dictionary item' with a key name: perhaps 'Read More' and then for each language setup for your Multi-Lingual Umbraco site you get at textbox to provide the alternative translated text version for 'Read More' in the various languages.

Some description

Some description

The idea being that inside your Umbraco Templates, Contour Forms, DocType labels etc, you can write out the dictionary item, and depending on the culture setting of the part of the Umbraco tree the page is displayed, the appropriate translation is used from the dictionary.

Something like: @Umbraco.GetDictionaryValue("Read More") will do the trick.

So this is great, one place for repeated phrases or small bits of text, saving editors from repetitive typing of the same thing and ensuring consistency, and ignoring for a moment that language translation is not necessarily that simple all the time, with the nuances of context and inflexion, the facility is there to provide language alternatives.

So you create a few Dictionary items for your site, they get translated all well and good. They rarely change. You probably followed some kind of naming convention, maybe you nested items in groups under other items, it made sense to you at the time, and possible to the editors.

However the problem kicks in when you inherit an Umbraco site, created by someone else, a long time ago, it's happening a lot - now at some point when creating a multi-lingual website in Umbraco it must have been fashionable to try and see just how many dictionary items could be created, and nested, a competition perhaps ? CG09??, with extra points for different naming conventions and case ? Was it possible to get Karma for creating dictionary items ??

Anyway even the most well thought out structure of dictionary items is difficult to follow on a large multi-lingual site, and we have been through a pattern of redesigns recently where phrases in the dictionary items needed to change; and nobody could remember what the relevant dictionary key's in the back office were called anymore...

And on some of these sites the editors did not have access to the Settings tab where the Dictionary sits (and it isn't straightforward to move this to a different section the way the permissions are checked - it should be in Translation, shouldn't it ?). On these sites we generally have the excellent DictionaryDashboard package installed, allowing editors to select the dictionary key from a dropdown, and edit accordingly.

Brilliant, but imagine for a moment I am French, (Oui, mon ami C'est vrai): I see on my site the phrase:

Il n'existe pas de résultat pour le critère sélectionné

I need to edit this phrase, but which Dictionary Key ?

DictionaryDashboard has a dropdown of all keys, but not in alphabetical order, and the key names are all English ?? it's not always obvious, Keep pressing and guessing ?

So I was getting fed up being asked which key, and guessing or having to look it up in the template; for 65 keys, for 25 translations, I exported a 'look up' spreadsheet...
 but it was still easier for them to ask, and even if they had the key they had to find it in the dropdown...

So maybe be good if you could just type the value in somewhere, for a particular language, and it tell you what the dictionary key was, and maybe find it in Dictionary Dashboard ?

So... Set the language and enter the translation you are looking for

Some description

 

It goes off look through all the dictionary items for the selected language to see if there is a matching value to the search text:

Some description

Voila! (as us French say): search results - you see the keyname, and the value (just to be sure) and if there are no exact matches it will do a 'contains' search.

Now instead of having to find the key in DictionaryDashboard's Dictionary Editor, click edit:

Some description

 

It finds it for you!

Anyway it's just another Umbraco 6 usercontrol, and you add to the same Tab you have the Dictionary Editor of the Dictionary Dashboard installed.

And the code is on GitHub here: https://github.com/marcemarc/tooorangey.DictionaryItemKeySearch

If you are in a similar position of inheriting and supporting multi-lingual Umbraco sites with award winning complicated Dictionary Key structures, then I hope this might help someone else out... or if one already exists, why didn't you tell me about it ?


Editor Notes for Umbraco 7

Written by @marcemarc on Monday, 19 May 2014
content - localhost (1).png

So you don't realise how much you use a thing until it's not there, and it turns out I seem to quite like using the Editor DataType that was in uComponents (http://ucomponents.org/data-types/notes/) courtesy of Matt Brailsford, to give little notes and prompts to editors in between doctype properties, just for bits of info that tended to get ignored when put under the label tag, or for longer descriptions, or warnings.

And I really needed to use it for this Umbraco 7 site I'm building, because the client (and probably me in six months time) will need prompting for how they can control their homepage layout, and it isn't something they'll change often enough to remember confidently how to do it, and it would just be great to have a brief explanation and possibly even a link to a how-to-video for them.

Homage

So I've created a homage to the original Notes DataType, as an Angular Umbraco 7 Property Editor.

In theory I'd just need a fairly simple view, and a controller to just write out the content of a PreValue field, which would contain the notes...

The PreValue Editor

... but the PreValue field would need to be a Rich Text Editor. That's ok that'll probably be one of the 'options' for PreValue editors in the core; but it isn't (and if you think about it, why would it be ?). Reading through Tim's post on advanced property editors: http://www.nibble.be/?p=377 - he lists the options for PreValue editors, but then also says you can use existing Property Editors as PreValue Editors (in fact he shows you can use them on themselves, scary).

So I just need a Rich Text Property Editor to use as a PreValue Editor, or how can I use the obviously already-there Rich Text Editor as a PreValue Editor ?.

Markus has talked a bit about using a Rich Text Editor in a dashboard control...
http://www.enkelmedia.se/blogg/2013/12/4/umbraco-7-use-the-rich-text-editor-tinymce-in-a-custom-section.aspx
... and reading through this led me to try a few things, and in particular the umb-editor directive. (oh good he has mentioned an angular directive, it must be a solution to a problem of some sort)

The umb-editor directive appears to load the correct editor based on the configuration passed to it. So by sticking one in my RichTextPreValueEditor view

<div ng-controller="RichTextPreValueEditorController" class="umb-editor umb-rte">
  <umb-editor model="editornotes"></umb-editor>
 </div>
 

and in the controller passing some configuration (note view: rte)

$scope.editornotes = {
            label: 'bodyText',
            description: 'Enter notes for editor',
            view: 'rte',
            value: $scope.model.value,
            config: {
                editor: {
                    toolbar: ["code", "undo", "redo", "cut", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbmacro", "umbembeddialog"],
                    stylesheets: [],
                    dimensions: {  }
                }
            }
        };

I was able to somehow manage to get the rich text editor to appear as a PreValue editor, by referencing the view direct from my prevalue fields' configuration in the manifest:

    {
                    label: "Editor Notes",
                    description: 'Notes to provide the editor on the doctype',
                    key: "editornotes",
                    view: "~/App_Plugins/tooorangey.EditorNotes/RichTextPreValueEditor.html"
                }

Some description
    

But it wasn't saving, which would have been a flaw, and I'm not sure why: you can see I'm using the $scope.model.value to be the source of the rich text editor, but the directive in the view was bound to the editornotes variable, and fiddling around I couldn't get it to work; so instead I've setup a watch on the editornotes.value property and set this to be the magic umbraco model.value, whenever it changed:

    $scope.$watch('editornotes.value', function (newValue, oldValue) {
      
            $scope.model.value = newValue;
        });

and now it saves ok !!

The Property Editor

So I had a Rich Text Editor as a PreValue Editor, I just needed to read the html from the PreValue field and bind it to an element with ng-bind-html attribute. Which was straightforward, however, only some html was coming through... the src of images and embedded iframes of that how-to video were stripped.

.. what on earth was going on ?

Well Angular being all super lovely and safe was just stripping out suspect markup when binding the html, in case it was user generated and somehow dangerous.
So I read the angular documentation and it seems you can tell angular ng-bind-html to trust the source of the html (using Strict Contextual Escaping $sce), and it won't strip it out:

 if (typeof $scope.model.config.editornotes != "undefined") {
     //angular 1.2 $scope.editornotes = $sce.trustAsHtml($scope.model.config.editornotes);
      
        $scope.editorNotes = $scope.model.config.editornotes;
    }

But why have you commented that line out then ? I hear you ask.

Well Umbraco isn't using angular 1.2 at this moment in time, and so you have to use a different old depreciated directive, called ng-bind-html-unsafe. So my view became:

<div ng-controller="tooorangey.EditorNotes" class="umb-editor umb-rte">
    <div ng-class="noteCssClass"><div ng-bind-html-unsafe="editorNotes"></div></div>
</div>

Summary

I've put the files on github, https://github.com/marcemarc/EditorNotes, it suited my purposes for this project, I can add messages amongst the doc types to the editor (use the css class to use the bootstrap alert classes for coloured context) and add my 'how to video',  but if you're stumbling across this in the future, there may be a version 7 uComponents with the original thing in done properly.

Screenshots

Some description

Some description

Some description

Update

You can install via:

Our Umbraco:
https://our.umbraco.org/projects/backoffice-extensions/ueditornotes/
Nuget:
Install-Package tooorangey.uEditorNotes

That International Telephone Input Jquery Plugin (the one with flags) as an Umbraco 7 Property Editor

Written by @marcemarc on Wednesday, 19 March 2014

Hey, so have been working on a few different multi-lingual International sites in Umbraco over the last couple of months, and the common theme for these is that International Telephone Number input and validation either inside Umbraco or on front-end forms is a bit complicated. Mainly because different countries have different length telephone numbers, so with regex's you end up saying well smallest number possible is I think 9 digits (Sweden ?), and the longest is 15...

So it's inprecise.

One client was adamant they wanted to force users to provide a valid telephone number, which I did point out was difficult without actually calling the person up and asking them "is this your telephone number ? did you just type it in online ?" (although if pushed I'm sure we could build something with http://www.twilio.com/ to automate this, scary thought)

I was thinking out aloud, if the customer puts 0 in the telephone field, it's not because they don't understand what their telephone number is, or what a valid format for a telephone number is, it's well, because they don't want to give you their telephone number, because you are going to try and ring them and sell them something, and well people don't always like that, especially if they are filling in a form online, and if your business is solely based on these telephone leads, then you might perhaps want to rethink it slightly because in 5yrs, 10yrs... is that sort of business going to exist ?

And then the client goes a bit sulky so I plugin the International Telephone Input Jquery Plugin (https://github.com/Bluefieldscom/intl-tel-input), and everyone is all smiles again - because it's got flags !! and the country codes, and it works with Google's libTelephoneNumber (https://code.google.com/p/libphonenumber/

Some description

and so it's pretty good at indicating what is a valid telephone number in a particular country or not, and the client is pleased because people have to fill in a valid telephone number and I don't point out: 'yes but they can still opt to put someone else's number in', and it's got flags.

Anyway such is the plugin's popularity, clients have begun asking for it within Umbraco for editing phone numbers, it's great for when the editor needs to specify the country code on a number from a country they're not familiar with, and so I've just had to wrap it up quite hastily today as an angular property editor, and I thought I'd put it up on our.umbraco as a package, in case someone else might make it better... or it may do for someone who is in a similar haste.

It's simple, there is one prevalue you can set on the property editor which is a json object as a string, that is any of the options provided for the International Telephone Input plugin (well I say any, I haven't tested them all, but you should be ok to set defaultCountry, preferredCountries and onlyCountries)

Some description

Then when a user fills in the number, there is a visual indication that the number is valid or invalid based on the selected Country flag,

Some description

Some description

it doesn't prevent the user saving an invalid telephone number, it just makes the editor aware that it is.  I think it's possible now or will be soon, to have a property editor take responsibility for it's validation within Umbraco, and so it could be set that a valid telephone number was required, and the page couldn't be published without one, but I didn't need that today, so it doesn't, ok ? but it has got flags.

I also needed to have more than one telephone field on the page, and I realised in the past I've been thinking too Jquery like, falling into the trap of manipulating the Dom from the controller, binding a plugin via a jquery selector of an ID, which is just plain wrong in angular.

(ASIDE, you may have noticed if you ever have a problem working out how to do something in angular it is only a matter of time before someone suggests using a directive, it's a cool thing to say, you know, if you're still at that bluffing stage).

So I've created a directive. A directive and don't quote me on this, is like a thing you can register and use in the html, that when it gets rendered fires some javascript, kind of (see http://docs.angularjs.org/guide/directive). So I've created an intTelNumber directive, and in the html set this on my input element, when this is rendered my directive fires, and my 'link' code has a reference to the element the directive is on, and I use this to bind the plugin to the control, so I don't need to know the id of the element in the html to trigger the plugin.

Directive:

app.directive('intTelNumber', function() {
 return {
// Restrict it to being an attribute
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function (scope, element, attrs) { scope.$watch('loaded', function () {
if (scope.loaded == true) {

// apply plugin
element.intlTelInput(scope.options);
//validate loaded number
var countryCode = element[0].nextSibling.children[0].children[0].className.split(" ")[1];
scope.validateTelephoneNumber(element[0].value, countryCode);

}}); }
}
});

Only problem was this was happening before the International Telephone Input plugin had loaded, so I put a $watch on property in scope called 'loaded' and changed this value to true when the assetservice concludes the libraries are there. it doesn't feel right, maybe I need to use a directive, oh..

The other tricky thing was I couldn't seem to access within the controller the IntTelInput plugin's existing 'isValidNumber' and 'GetCountryCode' properties and methods. Time was running out but I figured the way the plugin works is to store and retrieve the country code from a css class on an unrelated div element, just below the input element, so the hack to access this was:

element[0].nextSibling.children[0].children[0].className.split(" ")[1]

So it seems to work. You can try it out here.


uCssClassNamePicker Property Editor for Umbraco 7

Written by @marcemarc on Sunday, 12 January 2014
CropperCapture[326].jpg

Well if you've used the old uCssClassNameDropdown package in Umbraco 4/6 you'll be aware that bundled with the basic ability to create a dropdown data type from the values scrounged from the css stylesheet classnames that I also included a few usercontrols hard wired to work with font-awesome and bootstrap icons, and instead of the dropdown with lots of meaningless icon names the editor could actually see which icon to pick, and if we're honest it's probably this functionality that makes the whole thing a worthwhile endeavour rather than the basic dropdown thing, and I'm painfully aware of the dissappointed people have felt installing uCssClassNameDropdown for Umbraco 7 and the general constructive feedback has been "where are the *#?&!*+ icons ?"

So I could probably have rushed together a hardcoded font-awesome one relatively quickly, but times they-are-a-changin and there are lots of icons-as-a-font libraries out there, and I didn't really want to give the impression that uCssClassNameDropdown is just a font-awesome thing,  (even if in that is all people use it with) and I didn't want to keep updating a hardcoded thing everytime a new font-icon thing was invented The only thing that seems to differ in these libraries is the pattern of the <i class="icon icon-classname ... 

...So uCssClassNameIconPicker, is kind of the same as uCssClassNameDropdown except you can now set the 'Icon Pattern html' in the property editors configuration, that will render the necessary markup to display a version of the picked item

Some description

(where {0} represents the matched classname) eg:

{
 label: "Icon Pattern",
 description: "Html pattern to display icon, eg <i class='icon icon-{0}'></i>",
key: "iconPattern",
 view: "TextString"
}

Loading the stylesheet

For the Controller I needed to make sure that in order to render the icons from the stylesheet that the stylesheet was available inside the umbraco backend. to do this with Umbraco 7 I added the 'assetsService' to the controller function:

function ($scope, $http, assetsService) {

and then in the function which retrieves the classnames from the stylesheet added:

// load the supplied css stylesheet using the umbraco assetsService
assetsService.loadCss(cssPath);

Rendering the Icon

I created a helper method called 'renderIconPattern' to slot the matched classname into the specified iconpattern:

$scope.renderIconPattern = function (currentClassName) {
 return $scope.iconpattern.replace("{0}", currentClassName)
}

In the view (as per the old usercontrols) The basic dropdown is there as a fallback, but above this the icons are rendered in a list:

<li ng-repeat="ccn in classnames">repeating stuff here</li>

to render the icon, I made a call to my helper method using ng-bind-html (because the pattern contains raw html and I didnt't want it encoded) eg.

<li ng-repeat="ccn in classnames"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></li>

Setting the value

This got me a list of lovely icons, but the editor needs to be able to select them, with the old control I'd used jquery to bind to the click event, to set the dropdown value, which was then used as the saved value; but here all we need to do is set model.value, and magically the dropdown will change and the correct selectedvalue will be saved.

$scope.setSelectedClass = function (selectedClassName) {
$scope.model.value = selectedClassName;
}

and in my view added a link with an ng-click attribute set to the new method:

<li ng-repeat="ccn in classnames">
<a ng-click="setSelectedClass(ccn)"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></a>
</li>

Highlighting the selected icon

Determing if an icon is the selected one, again achieved by a helper method in the controller:

$scope.getSelectedClass = function (currentClassName, selectedClassName) {
 if (currentClassName == selectedClassName) {
 return "selected";
 }
 else {
return "";
 }
 }

and in the view, we use ng-class

<li ng-repeat="ccn in classnames" ng-class="getSelectedClass(ccn,model.value)" id="iconHolder-{{ccn}}">
<a ng-click="setSelectedClass(ccn)"><span ng-bind-html="renderIconPattern(ccn)"></span><span>{{ccn}}</span></a> </li>

Some description

it's starting to make a bit of sense to me but...

.. the thing that is not quite right which has bugged me and prevented me uploading this to Our, or blogging about anything and taken more time the rest of the control is the scrolling. It's fine if a user scrolls and selects an icon; but if they use the dropdown the icon doesn't scroll and they can't see which icon is selected.

Angular has an $anchorScroll service which looks neat, but requires you to set the $location in order to scroll to a position, and that was mucking up Umbraco 7's routes, it may be the way to resolve it but in the end I just used animate, to sort of fake a scroll, and this sort of makes it usable, but it isn't perfect, and I've noticed that if the control is on another tab, and the edtior switches to that tab, they won't see the selected icon; so as a temporary workaround, the selected icon will appear next to the dropdown; and I'll think about it a bit more.

The interesting angular part of this, is I set up a 'watch' on the model.value so whenever it changes I can run code, and I have a function called 'goToIcon' which animates to the selected icon.

$scope.$watch('model.value', function (newValue, oldValue) {
$scope.goToIcon(newValue);
});

 This version can be download as version 7.0 from our.umbraco.org

 


Some notes on Upgrading to 7.0.1 from 7.0.0 or from RC

Written by @marcemarc on Thursday, 09 January 2014

So the blog is now running v7.0.1 of umbraco, quite a few little things have been fixed which is nice. A couple of things I encounted I'm writing down here mainly so I remember, so feel free to skip this post.

 

Login no icons

If you login after upgrade and you've got no left hand section Icons even though your account is admin, you just need to clear the cookies for your site on your machine.

Refreshing cache

Also if you are developing in Angular with Umbraco, and trying to get something to work, and you're not sure whether it's cached, (ctrl F5 doesn't appear to work etc) and you feel like you are going slightly mad then in Chrome if you are running in developer mode, when you hover over the refresh icon you get some extra options, one of which is 'Empty Cache and Hard reload' that does it! - and suddenly you have days of your life back to do something creative instead of seething at why 'Hello World' hasn't been alerted to the screen.

Some description

Disappearing Images

If you drag images into Umbraco to upload, and they tantilisingly stay in the window for a second before disappearing without any error message, and you've tried upping the maxrequestlength value in httpruntime; like you would in Umbraco 4 with no joy. If you try to create the media image without dragging and dropping you get the following error. about ContentDispositionHeader cannot be cast:

Some description

Then this is probably because you've upgraded or pulled Umbraco using Nuget, and it's made a change to the version of the System.Net.Http dependant assembly in web.config just change:

<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>


to:

<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

and everythng is ok again.