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...
Ok there is a big slab of a gap on the homepage... maybe on an intranet and the client says "oh that will be an RSS feed of the latest news or weather or something…" - because they want the page to be some kind of 'hub' for all information on the internet that might be of passing interest to their users/employees etc - although of course that isn’t how people use the internet is it?
What's really going on here is you have a big white space next to the company Twitter feed... And well, the output from an RSS feed would be about the same size.
Anyway, after sighing inwardly, you dig out that code from 2012 and if you were smart back then, you would have stumbled across the SyndicationFeed class from that then version of the .Net framework and you'll do the same old thing you always do to display the feed.
In Umbraco then, you're left with a dilemma, this is code, c# code, it shouldn't be in a razor view, although it's only a few lines? should I? should it be a Surface Controller Child Action - should I hijack the route? or....
... why not a property value converter?
is that really the right answer?
The use case
This package / custom property editor thing came from an editor on a site we support needing to update the RSS feed Url on their website homepage, they found the new RSS feed link, clicked it, saw the raw feed in their browser. satisfied, they copied the url from their address bar, and pasted it into the RSS feed textbox property in Umbraco, on their homepage node - published and boom... the url was missing the last few characters, bad cut-and-paste! ... their homepage was down!
Wouldn't it have been great if they could have checked the feed Url was working before they published the homepage?
Now they can!
Replace the textbox for the RSS Feed Url in the umbraco document type with a property editor of type tooorangey.RssFeedUrl.
Now after the editor has cut-and-paste the feed Url, they have a Check Feed Url button to press.
If there is a problem with the feed, they are alerted before the homepage is republished, before the boom!
and can check and correct the feed Url accordingly...
If the Url is an active RSS Feed, the editor sees a tick and a reassuring 'Valid Feed Url' message! - ahh but is it the right feed? a Preview button enables the editor to see the current contents of the feed, to check, again before they push the publish button.
Those first two items are not fake news as far as I know.
I'm not doing anything super clever to validate the Rss Feed, I'm just seeing whether the SyndicationFeed class can open and read the url and whether there are any feed items.
(Why doesn't the editor use Umbraco's page 'Preview' button before publishing instead...? well you are less likely to use this button for changes to an existing page, and also less likely to for 'non content' changes [Citation Needed]- this button gives the editor a subtle 'in context' reminder, that changing or adding this feed url is something worth checking, and it's convenient to do so at the point of entry)
But what about the Property Value Converter ?
Well the work in the plugin to pull back the feed contents based on the feed Url may as well be made available to be used in your razor view or surface controller...
so if your property has an alias of rssFeedUrl, something like this will now pull back the feed contents:
The FeedResult class has four properties, the FeedUrl (in case you want to do something with the raw url) and a boolean flag 'HasFeedResults' that you can use to determine if there are any feed items to display, if there is an error, it will be logged and the StatusMessage will give some indication of the message. Finally the SyndicationFeed property is the .Net SyndicationFeed class mentioned above, and contains all the details you need to know about the RSS Feed you are consuming and it's feed SyndicationItems.
It's worth putting the above in a Macro/CachedPartial/OutputCached Surface controller to add some caching so you are not requesting the feed ever time the page is refreshed.
Anyway, the snippet above produces something like the following:
but you can customise the html and css to use with your feed content.
... now the next time you are asked to add an RSS Feed to a page, I cannot promise you that your inward sigh won't still occur, a simple property editor can do nothing to temper the sigh of a developer that has been asked to add an RSS Feed to a page for seemingly little reason by very well meaning people, but I can hope, that the thought of demo'ing this small crumb of helpful functionality and the smile of gratefulness you may receive in return could temper you from responding with a tired sulky "really?, well it's technically possible but...
So recently we helped upgrade one of our support client's Umbraco sites from v6 to v7, all went very smoothly, except suddenly...
...puncturing their haze of post upgrade bliss was the shocking realisation that they were entirely in love with the Cogworks CogPageReview dashboard and actually their entire world of workflow revolved around this simple content review date dashboard - and it wasn't in fact 'something they didn't really use and could live without' - but something they needed superfast, or otherwise, well... some content might get old and nobody would know....
I've come across this deceptively simple package a few times before, and people just tend to believe 'it's part of Umbraco', particularly for large sites containing public information that will only be valid for a certain period of time, you set the content review date, and don't have to remember to check next year, it's invaluable.
Anyway onsite I knocked together quickly a dashboard to do a similar job in Umbraco 7, and you can download it here for the time being, if it helps you out, and hopefully we can push this back into the original package, but what I have here is pretty hasty, it's working so far... fingers crossed.
... but hey that isn't what this blogpost is about...
So what I wanted to blog about was three small things I noticed putting this together that I sort of didn't really know about or had learnt recently from the above course and also had spotted in the refactoring of the 'proof of concept' (for proof of concept, read not very good) Redirect Dashboard that HQ ahem refactored for the 7.5 release - that seemed new to me and I thought were mildly worth talking out loud about, here they are:
1) Don't use $scope 'willy nilly'...
So I'd got into the habit of using $scope all over the place, and when we introduced property editors to the Umbraco Level 2 course we taught this approach - officially from the docs:
$scope as a Data-Model "Scope is the glue between application controller and the view." and so enables your directives, controllers and views to share values and communicate in an agnostic manner.
Anyway cool kids don't seem to do it like that anymore - looking at the Redirects dashboard the preferred pattern moving forward for Data Models is to declare a ViewModel object or vm for short!
so here I'm grouping the dashboard status and settings on an object and for some reason to me it seems to make the controller much much easier to read...
... and you don't need to inject $scope into your controller unless you are using it for non data model purposes, eg setting watches and the like.
2) Backoffice styling - flexgrid and pagination, particularly pagination.
Making things look good in the backoffice has always been a bit of guesswork over what is there, and providing your own styles, which then as Umbraco changes start to look a bit weird... what package creators need is a style guide for property editors and dashboards that they can use to keep the look and feel of their creations consistent with the vanilla backoffice... the good news is I'm told the style guide is very much a planned thing that will happen soon.In the meantime if you are presenting tabular data, the redirects dashboard has the most recent HQ approach to this kind of thing and the first thing you notice is Flexbox for table layout is in the core, was that always there? I don't know, but it's certainly worth being aware of and utilising!
The most exciting thing though for me, because I hate implementing paging... is there is a new directive called 'umb-pagination' <umb-pagination - to consistently handle paging ui in the backoffice, and it's really easy to repurpose: so all I needed to do here was to create a pagination object on my viewmodel with totalPages, pageNumber, etc, populated from my search results
also we have an <umb-loading-indicator directive to handle the interaction when it takes a while to build the report
and an <umb-empty-state to show a message when there is no content review...
3) Finally language translations of text within the dashboard
I've always kind of wanted to provide the opportunity for people to translate the text used within a property editor or dashboard I'd created, but never really understood how. It's not just cos I'm English and think people from other countries will undertand if I just talk louder... anyway this isn't new, but is all setup by convention and so it might not be apparent what to do.
In your angularJS dashboard view or property editor you can use the <localize tag with a key and a default value (there is also a localize service if you need to work with the translated text in your controller)
Written by @marcemarc on Thursday, 06 October 2016
Today, the 6th of October is National Poetry Day - when I was younger, so much younger than today I used to write awful urban romantic poetry, (marcemarc completists can find out more here: http://daysdrawout.co.uk/posts/the-panda-keeper/). Anyway I've often thought there is a similarity between beautiful code and poetry, the metre, readability, code blocks are like verses and of course whilst your code needs to compile - it does not have to rhyme...
oh and Poets and Coders seem equally obsessed with late nights and drinking coffee.
...with Umbraco and it's interfaces beginning with I, and all those package names beginning with u - my mind has often thought it should be possible to construct an Urban Romantic poem containing entirely references to classes and interfaces in the codebase and umbraco package names...
but of course that is ridiculous and here's the proof:
It would be a good openspace session to discuss creating a library of common Umbraco coding patterns, showing off variations of how to implement common functionality, or even a library of common Compositions, that you could select, and download into your Umbraco site...or something.
Editor notes has been Steinmeiered... Greystated; well Umbraco legend Chriztian has been using it and having ideas.
Principally it's all very well having this huge colourful Editor note reminding, sometimes nagging editors to do a thing in a certain way, (and the idea is to use this on areas not used that often), but there becomes a point, if you are an editor, and you use the site everyday, that a well meaning note, well it becomes irritating and patronising and takes up screen space and therefore infringes on an editors sense of wellbeing, particularly if you done a good grammatical error in the text of the note, or made a sentence too long, with too many commas and ands.
So now there is an option to configure the note to be 'collapsible' - the editor can read the note, and then decide 'they got it' and hide it, expanding it later lest they forget. (The state of collapsibility should be remembered using browser local storage for each note.)
So setting the Node Render Mode to 'Html' means everything is as before, 'Collapsible' gives you the new functionality and 'SlidingPane' is another alternative that will slide out a panel containing the note.
The latest version is .3 and is available and updated on Our Umbraco and Nuget too (Install-Package tooorangey.uEditorNotes).
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)
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
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.
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:
"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.
Not only will your editor appear in the list of property editors, it will now be available as a Macro Parameter Type too !!
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.
Which 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:
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.
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...
or for those of you following along in the lovely new 7.4 UI:
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!
Update August 2018
Dave Woestenborghs (@dawoe21) says:
just don't try that on cloud..because it will break your deployments. Main reason why this PR is not merged yet :
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]),
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
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.
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.
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...
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.
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.
- 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:
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.