Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / weblog

Dominic Cronin's weblog

Dominic is no longer a geek

Posted by Dominic Cronin at Mar 03, 2013 10:08 PM |

For as long as I've run a web site at www.dominic.cronin.nl, I've run the server at home, and used the free services of DynDns to take care of the fact that my Internet Service provider assigns my IP address dynamically.The way this works is that DynDns have a list of domains that they will let you use for free by assigning you a sub-domain. One of these domains (perhaps the most famous) is "is-a-geek.org". For the last several years, I have had the use of "dominic.is-a-geek.org". For free. So thanks DynDns. There's a protocol for automatically updating the IP address associated with this name, so should I ever get assigned a different IP, the dynamic DNS name would stay pointing to the right place. When you type in "www.dominic.cronin.nl" into your browser, it actually goes to the DNS services at Qweb somewhere near Rotterdam, who host the records for my "real" domain name. The response you get from there includes a CNAME record pointing at dominic.is-a-geek.org (or at least it did), and for all practical purposes, you end up at the right place.

Of course, it's great that DynDns offer these free services, but sooner or later they want people to upgrade to their paid services, so for the last few years they've made it so that you have to "refresh" your free name every month. They send an email, you click on a link, and all is good. At least until today, when i realised that not only had my free name expired, they also wouldn't give it back to me if I wanted to stay a cheapskate. They had obviously cottoned on to the fact that the is-a-geek names are desirable (to some people). So there it is. My long-standing use of dominic.is-a-geek.org is over. The end of an era, I suppose.

For what it's worth, I'm still using a free DynDns account, but now it's "dominic.dyndns-home.com". Doesn't have the same ring about it, though. :-(

Fortunately - these days, QWeb have an excellent web administration interface, and within half an hour of realising the problem, I had it all joined up and working again. So I might be QWeb's most insignificant customer - it's hard to imagine anyone buying smaller amounts of service from them - but I'm definitely a happy customer.

As for DynDns - sure, I'm crying inside, but really - you can't accept free service for years and then whinge about it. It wouldn't be right, especially as they are still keeping my site running.

Alt text, title text and web content management

Posted by Dominic Cronin at Mar 03, 2013 09:35 PM |

I've been reading Alvin Reyes' recent blog post about "alt" text for images, and how you should manage it in Tridion. That triggered me to think about a few of these issues, and I'd like to respond to Alvin's post, and perhaps also broaden out the discussion a bit.

The typical scenario he describes is that you have a "content" component which links to a multimedia component representing an image. In the web site output, of course, the alt text needs to be associated with the image, but Alvin raises some questions over where we should manage this data in the CMS. He starts off by saying that the "Common practice" (of putting the alt text in the metadata of the multimedia component) is wrong, and that instead you should put the alt text in the content component. OK - so he then goes on to show that he understands the practical benefits of keeping the alt text with the image, and suggests a couple of other approaches, including putting the data in both places.

What Alvin describes may indeed be good practice for some organisations, but so much depends on the requirements. I think perhaps the most important take away from this discussion might be that unless you can elicit accurate requirements, you are going to get this wrong. Let's face it, the "common practice" technique is pretty solid. You have metadata that describes an image, so you manage it with the image. This isn't just an 80:20 rule, it's a 99% rule. The cases where you need multiple descriptions of the same image are rare in practice. Perhaps the obvious exception is where you're using the image as a link. Stop there a second... I mean the case where you're using a meaningful image to link to something and the description of your linking image is inappropriate for your link target.

OK - before I get carried away, let's deal with this. Firstly - there ought to be various distinct multimedia schemas in your site, intended for different purposes. Having a single "Image" schema is probably an anti-pattern. Tridion schemas have great support for constraining the choice of multimedia schema in helpful ways. (Although maybe it's weaker in Rich Text format areas). If you really, truly have a site where simple 80:20-rule alt text down on the bare metal doesn't work, then you can probably isolate the difficult cases to a particular image type or types. Obviously, you will want a schema for layout images (Lime green bullet, gothic top left corner, and so forth.) This schema should not allow for alt text, and the templating should always emit an empty alt attribute.

Then let's imagine we have a News schema, which allows for a relevant picture. When displaying the detail view of the news item, you obviously want the alt text that describes the image. "President Obama concedes defeat to the President of the NRA, at their meeting at the Whitehouse". When you render the thumbnail variant of the same image in a list of news items, the alt text will tell you that it's a link, and use the title of the news item. "Link to: Hope dies for gun control as Obama confirms his commitment to 2nd Amendment". You don't need to store any extra metadata to do this. Your multimedia schema (News event image) has exactly the metadata it needs, and your news item schema allows you to use multimedia components of this schema for adding a picture of the news event being described. (Should you also have a distinct schema for pictures whose only purpose is to look nice?)

Of course, there are sites where a high value is placed on accessibility, and where they'll do everything. Often these are government sites, or those of large enterprises that can afford the investment in keeping a squeaky clean image on how they treat the disabled. This still isn't the majority, though - by any means. The rest don't want to pay for it, and by that, I don't just mean they don't want to pay for the extra complexity in implementing all the bells and whistles. Perhaps even more to the point, they don't want to invest the extra effort that it will cost their "content" department to actually work with all this extra detail. To achieve an accessible web site, you need more than just clued-in technologists. The web content people need a pretty sophisticated understanding of the issues too. For alt text, they need to know when it should be empty, and they need to know how to write it with the right amount of context when it is needed. Generally, if you have optional fields in your schema, you'll need fairly good editorial control to ensure that it gets filled in at all. When your implementation has some sort of fallback mechanism that puts in a default when you leave it empty, how are you going to deal with that? An extra checkbox next to the alt text field that says "Yes, I really meant to leave it empty". (I'm joking, but if you're doing the site for a blind peoples' charity, you might even go to these extremes). So even with all the complexity built in to your implementation, you're still going to have to send all the content workers on courses where they get to play with screen readers and live for a day like the visually disadvantaged part of their audience, and then you're going to have to repeat this often enough to keep it real next year, and the year after.

So - most organisations aim way lower. If I had a Euro for every professional web content worker I've met who didn't know the difference between title text and alt text, I could probably go on a nice holiday. This is by no means a tirade against the content workers. Most of them are working very, very hard just keeping their sites updated, and it's no wonder they just want the CMS implementation to magically take care of all that accessibility stuff. If you put a separate field for alt text and title text, or a separate field for alt text in a different context, they will probably write something straightforward, paste it in all those places, and then curse you (again) for an idiot for making them do that last step (again). And then they'll go home and tweet that they hate Tridion.

So again, it's about the requirements. Requirements, requirements, requirements!. If your organisation is very, very keen on getting this stuff right, then your shiny new implementation isn't going to help them unless they plan for those training sessions for the web team, and then allow the content team to adjust their estimates on every new piece of content to allow for all that extra effort.... It's half past four in the afternoon, and someone in marketing or communications has emailed them a word document with the text of the press release that absolutely must hit the site at midnight tonight. Knocking-off time is half past five, but what the heck, we'll stay late to show commitment, but really, if I'm staying late it had better be for something more profound than faffing around with the third variation of the alt text. The chief editor might just bother to look for a tooltip on the image if they are on the ball, and the rest of the team are already in the pub. Whatever!

So really - if you are in that elite group that wants to do full-on accessibility, and understands and is willing to deal with the implications, good for you. Alvin's "ultimate practice" might be for you, but that'll be OK, because the team will know enough to be able to work with it. If, on the other hand, you want to do the right thing (so presumably you'll go at least as far as some moderately good alt text) the best bet might be to just stick with putting the alt text in the image component, and re-using this text for the title attribute. At least, make sure you have the requirements discussion, because the costs are very clearly not just one-off implementation costs. Even that copy-paste-paste-paste cycle will cost them time and patience every single day. Anyway - my point is that the web content management implementation needs to support the actual practices that people want or expect to follow in their day to day work.

While we're on the subject... when exactly was the last time you sat down with the person responsible for the web site and discussed the need for quote tags, or longdesc attributes? Isn't it about time?

Tridion Practice moves to GIT

Posted by Dominic Cronin at Mar 03, 2013 12:10 PM |
Filed under:

Back when Tridion Practice began in 2011, most of us were happy enough to use Subversion as the underlying version management system. Since that time, distributed versioning systems have shown their usefulness, and if I'm starting a new project these days, I generally begin by setting up a GIT repository. Tridion Practice is hosted at Google Code, and since those early days, they have added support for GIT, so it was just a matter of time before we ended up moving. To be honest, this was a bit of a dry run for moving the Tridion Power tools on to GIT. The power tools project has far more active committers working on code, so there are even more benefits to be had there. We discussed it in the team, and at first there seemed to be a consensus that it would be good to do this before SDL Tridion release their "2013" product, which will inevitably bring changes to the power tools: most likely a new branch at the least. In practice, getting a team that size all saluting the same flag is a bit more difficult, and sometimes consensus is more valuable than progress.

Git comes with some pretty solid tools for migrating from Subversion, and the Google Code support pages have a guide for migrating one of their projects from Subversion to GIT. Even with that guide, I found I had to read around the subject a bit first before having the confidence that I could follow the instructions well enough It's funny how much you come to rely on your source repository "just working", which leads to an extra bit of care in doing the migration. But, having taken that care, I can now report that the switch over went without a hitch.

Debugging 64 bit Tridion content delivery on IIS 7.5

I'm currently developing a web application which will run on Windows 2008 R2 and which is intended to run in a 64bit Application pool. This means that I'm running IIS 7.5, and that the web application is installed with the 64 bit versions of the Tridion content delivery assemblies. As you'll know if you've tried to run this kind of web application in a 32 bit process, you pretty soon get exceptions telling you that you have an invalid format. This gets a little inconvenient if you just start to debug your web application in Visual Studio. By default, if you have a page selected, and hit the big green Run triangle, the page will launch in IIS Express. If you have IIS 7.5, then IIS Express runs a 32 bit process, so the default setup just isn't going to work for you.

So - what to do? I had two options:

  1. Configure the properties of the web application to debug using IIS rather than IIS Express
  2. Launch the web page directly from the browser, and attach the debugger to the correct w3wp.exe process.

 

To be honest, the second of these was the choice that most matched my usual debugging approaches. Having said that, I did try the first approach, but so far without success. Visual Studio 2012 has frozen on me a few times while trying this. I'm interested if anyone has any tips on getting this working, but right now, I'm happy enough that I was able to succeed in attaching a debugger to w3wp.exe.

My biggest challenge was to figure out which process I wanted to attach to. On my development server, I have quite a few web sites running, and it's not altogether obvious which w3wp.exe to attach to. Attaching to them all might work in a trivial case, but realistically, it takes quite a while to load all the dlls, and adding any more processes than necessary is just going to hurt too much. So - how do you find out which process it is?

The first step is to ensure you have the IIS powershell provider installed on your server. These days, this is shipped as a module, so if it's available on your system, you should be able to open a powershell and type:

Get-Module -ListAvailable

If the response includes "WebAdministration" you are good to go. Just import the module as follows:

Import-Module WebAdministration

If this succeeds, you should be able to "change directory" into the IIS provider. (Although a PowerShell purist might prefer set-location... whatever floats your boat!)

cd IIS: 

If you can't find the module, then go into the Server manager, and check that you have the relevant role services for IIS installed. On other platforms, you might find that you can install it from the WebInstaller from the MSDN web site.

Now you're ready to find the process that you want to attach to: Assuming that your application pool is called "MyApplicationPool", then you can list its worker processes like this: (or use "dir" or "ls", either of which is an alias for "gci")

> gci IIS:\AppPools\MyApplicationPool\WorkerProcesses
Your output should look something like this:
Process  State      Handles  Start Time
Id
-------- -----      -------  ----------
2608     Running    776      1/2/2013 6:55:33 PM

This assumes, of course, that your app pool is actually running, but you'd have made sure it was before trying to debug it, right. Anyway - as you can see, the process id is there just to read off, and you can get straight on with your debugging session.

Mysterious 404 errors showing up in the Tridion message centre

Posted by Dominic Cronin at Dec 19, 2012 11:37 PM |

Today I spent some time setting up a Tridion 2011 Content Manager server. In fact, the content manager had already been installed and had been working fine. Then we'd installed Microsoft Search Server. OK - so it's quite unusual to be doing quite so much all on one server, but this is a customer with minimal needs. Not everyone has 200 servers in the rack! Although Search Server is packaged as a product in it's own right, it's built on Sharepoint, and when you install it, it seems to bring two thirds of Sharepoint with it, including 2 MSSQL instances and three web sites. So to get the benefit of Microsoft's "free" search services, we'll probably have to configure another couple of gigs of RAM. (SFX: Sound of a cash register going "ca-ching" at VMWare headquarters)

Anyway to be fair, the search solution looks pretty good and it definitely does what it says on the box, although it's got about a hundred configuration screens (I haven't actually counted them, though). Well anyway - we'd installed this beast on our previously working Tridion server, and most things were going OK. Until I did an IISRESET, and then suddenly the Tridion CME started to complain about a 404 problem. So when you started the CME, you'd get error messages like:

The remote server returned an error (404) not found

On examining the message centre, I found this message 6 times, along with "Loading list of languages failed" and "Loading list of locales failed". Sure enough, the relevant drop-downs in the User preferences are not  populated.

When I F12'd the browser. (Is there a verb, to F12? There should be.) I could see that the browser wasn't seeing any responses with HTTP status 404. So what was going on?

After digging a bit on the server, I found that there were entries in the web server log like this:

2012-12-19 12:59:41 ::1 POST /WebUI/Models/CME/Services/General.svc/GetListCustomPages - 80 BLAH\Administrator ::1 - 404 0 0 58
2012-12-19 12:59:41 ::1 POST /WebUI/Models/CME/Services/General.svc/GetListFavorites - 80 BLAH\Administrator ::1 - 404 0 0 62
2012-12-19 12:59:41 ::1 POST /WebUI/Models/CME/Services/General.svc/GetListSystemAdministration - 80 BLAH\Administrator ::1 - 404 0 0 15
2012-12-19 12:59:41 ::1 POST /WebUI/Models/TCM54/Services/Lists.svc/GetList - 80 BLAH\Administrator ::1 - 404 0 0 30
2012-12-19 12:59:41 ::1 POST /WebUI/Models/TCM54/Services/Lists.svc/GetListEnumerationValues - 80 BLAH\Administrator ::1 - 404 0 0 5
2012-12-19 12:59:41 ::1 POST /WebUI/Models/TCM54/Services/Lists.svc/GetListEnumerationValues - 80 BLAH\Administrator ::1 - 404 0 0 8

So I could see from here that the errors were taking place when the CME web application made a local call-back on the server to it's own service layer. A bit more poking around showed that the problem was displayed whenever the CME made a callback to a service.

So what was going on? (Did I ask that already?)

It turned out that installing large portions of Sharepoint had had the undesired effect that the Tridion CME web site no longer owned the default binding. We had a host header binding mapped in IIS, and you could reach this just fine, but since the install, traffic aimed at 'localhost' was going to the wrong web site. Actually, Tridion has got this covered, because in the WebRoot Web.Config there's a an app setting called "Tridion.WCF.RedirectTo". This was pointing to localhost (which had worked fine when the server was first intalled). So when the CME tried to make calls back to the Model services, it was aiming these calls at localhost, which of course, ended up in the sharepoint site and a 404.

We fixed the immediate problem by editing the IIS bindings, but we're considering whether it might be good practice to always configure Tridion.WCF.RedirectTo to go to the name of your site, and not to localhost.

The relevant Tridion documentation is here,

Tridion Explorer reports System.ServiceModel.ServiceActivationException

Posted by Dominic Cronin at Dec 15, 2012 08:50 PM |

I'd been noticing strange messages popping up in the message centre of the SDL Tridion Explorer. The messages were about some service call failing with a 500 status and System.ServiceModel.ServiceActivationException, and seemed to be coming from various service points under C:\Program Files (x86)\Tridion\web\WebUI\Models\TCM54\Services. Here's an example:

/WebUI/Core/Services/Communicator.svc/Invoke failed to execute. STATUS(500): System.ServiceModel.ServiceActivationException

Not all the time, just occasionally when I did certain things. The thing that got me irritated enough to do something about it was when I wanted to delete a list of old versions of some items, and the multiple items functionality was breaking, and throwing up these messages. I could delete them one item at a time, but not all together. I suspect you can get problems with other things too, looking at the list of services that are served the same way from Models\TCM54\Services, and I think I remember also having problems with publishing and where-used.

A bit of Googling pointed me in the right direction, and I ended up after a couple of false starts editing: C:\Program Files (x86)\Tridion\web\WebUI\WebRoot\Web.Config

What you need to do to fix the problem is to add some configuration to get WCF to behave properly. On my, now working, system, it looks like this, but YMMV.
<serviceHostingEnvironment>
  <baseAddressPrefixFilters>
    <add prefix="http://localhost/"/>
  </baseAddressPrefixFilters>
</serviceHostingEnvironment>
Actually - once you're poking around in the web.config file, it's pretty easy, because it turns out that Tridion have already included the relevant configuration, commented out.
It may be that it's also called out in the installation documentation, and that I've missed it. Anyway - joining up the dots between the symptoms and this particular piece of config isn't so obvious, and it's always possible that you set up your system correctly and then add a new name binding in IIS, So therefore this "note to self" post, which will maybe help me to remember the extra step that's needed. And it can't hurt to have the cause and solution in close proximity in a Googleable location. :-)

Using helpers in Tridion Razor templating

Today, for the first time, I used a helper in a Razor Tridion template. I'd made a fairly standard 'generic link' embedded schema, so that I could combine the possibility of a component link and an external link in a link list, and allow for custom link text. (Nothing to see here, move along now please.)  However, when I came to template the output, I wanted to have a function that would process an individual link. A feature of Razor templating is that you can define a @helper, which is a bit like a function, except that instead of a return value, the body is an exemplar of the required output. There is also support for functions, so to lift Alex Klock's own example:

@functions {
    public string HelloWorld(string name) {
        return "Hello " + name;
    }
}

and

@helper HelloWorld(string name) {
    <div>Hello <em>@name</em>!</div>
}

will serve fairly similar purposes.

What I wanted to do today, however was slightly different; I didn't want to pass in a string, but a reference to my embedded field. All the examples on the web so far are about strings, and getting the types right proved interesting. I started out with some code like this:

@foreach(var link in @Fields.links){
  @RenderLink(link);
}

So I needed a helper called RenderLink (OK - this might be a very trivial use-case, but a real problem all the same.). But what was the type of the argument? In theory, "links" is an EmbeddedSchemaField (or to give it it's full Sunday name: Tridion.ContentManager.ContentManagement.Fields.EmbeddedSchemaField) but what you get in practice is an object of type "Tridion.Extensions.Mediators.Razor.Models.DynamicItemFields". I'd already guessed this by poking around in the Razor Mediator sources, but after a few of my first experiments went astray, I ended up confirming that with @link.GetType().FullName

Well I tried writing a helper like this:

@using Tridion.Extensions.Mediators.Razor.Models 
@helper RenderLink(DynamicItemFields link){
... implementation
}

but that didn't work, because when you try to call the methods on 'link' they don't exist.

And then, just for fun, of course, I tried

@using Tridion.ContentManager.ContentManagement.Fields 
@helper RenderLink(EmbeddedSchemaField link){
... implementation
}

but that was just going off in an even worse direction. Yeah, sure, that type would have had the methods, but what I actually had hold of was a DynamicItemFields. Eventually, I remembered some hints in the mediator's documentation and tried using the 'dynamic' keyword. This, it turns out, is what you need. The 'dynamic' type lets you invoke methods at run-time without the compiler needing to know about them. (At last, I was starting to understand some of the details of the mediator's implementation!)

@helper RenderLink(dynamic link){
... implementation
}

This may be obvious with hindsight (as the old engineers' joke has it ... for some value of 'obvious') . For now, I'm writing another blog post tagged #babysteps and #notetoself, and enjoying my tendency to take the road less travelled.

TWO roads diverged in a yellow wood,
And sorry I could not travel both
And be one traveler, long I stood

And looked down one as far as I could


To where it bent in the undergrowth;
Then took the other, as just as fair,
And having perhaps the better claim,

Because it was grassy and wanted wear;


Though as for that the passing there
Had worn them really about the same,
And both that morning equally lay

In leaves no step had trodden black.


Oh, I kept the first for another day!
Yet knowing how way leads on to way,
I doubted if I should ever come back.

I shall be telling this with a sigh


Somewhere ages and ages hence:
Two roads diverged in a wood, and I—
I took the one less traveled by,
And that has made all the difference.

-- Robert Frost

Enabling XML syntax-highlighting for .config files in gVim

Posted by Dominic Cronin at Nov 23, 2012 10:15 PM |

I've used the vi text editor for many years; (at least long enough to know that it's pronounced vie and not vee-eye!). Over those years my level of expertise has varied somewhat - I'm fairly sure I've learned some commands and forgotten them several times over. Anyway - recently (i.e. in the last year or so), I've put some more effort in to reacquainting myself with some of its many joys. In practice, of course, I really mean vim: I'd be hard-pressed to remember the last time I saw vi in its "good-old-fashioned" form (does one say Plain-old-vi?) As most of my work is on Windows systems, this means using gVim.

Of the many improvements that vim has over vi, syntax highlighting is one of my favourites. The trouble is, one of my commonest use-cases for editing text files on Windows systems is .NET configuration files. Because these have a file extension of .config, they aren't recognised by default as XML files, and I end up going through the rigmarole of selecting one menu option to get a choice of file types added to the menus, and then locating XML among those newly added options to get highlighting to come on. Well there had to be a better way, and of course there was. What you have to do is this:

  • Locate your vi directory (on the system I was working on this evening, it's "C:\Program Files (x86)\Vim\"
  • Having found this directory, locate or create C:\Program Files (x86)\Vim\vimfiles\ftdetect
  • In ftdetect, create a file called config.vim with the following contents:
au BufRead,BufNewFile *.config     set filetype=xml

I have Windows configured to use vi as the default editor for .config files, so now with this in place, all I have to do is double-click on the file and it opens with XML syntax-highlighting enabled. Great stuff!

Templating unbalanced tags in the Razor Mediator

Posted by Dominic Cronin at Nov 17, 2012 05:30 PM |

I've recently started using the Razor Mediator for Tridion (http://code.google.com/p/razor-mediator-4-tridion/) on a project, and it's been an interesting experience. To be honest, I wondered at first whether it would shift my views further in the direction of putting code in the templating layer, but I suspect I'll probably remain a die-hard token replacer. I did start at first with writing rather more C# in my templates than I generally would, but the reality is that the complexity always increases, and pretty soon you find yourself wanting to debug the code in Visual Studio. Then I'd rather have it in an assembly of its own. (OK - maybe there are, or could be, techniques for debugging your code in-place in the Razor template, but I'm not sure if the game would be worth the candle.)

Having said that, a few simple loops and if-blocks should be perfectly OK in the templating layer, which brings me to the subject of this post. My design has a page template which manages a list, in which the <li/> elements are created by a component template. The responsibility for the <ul/> belongs in the page template. (Yes - I know, but I've thought about it, and for what I'm trying to do, this is what makes the most sense.) So what about the scenario where they don't place any of the relevant component presentations on the page? Then I don't want the <ul> or the </ul> either. So I looked at the examples, and found how to do an if-block. How hard can it be, right? But this was where I hit another of my #babysteps learning points, which I'd like to share.

If you want to have an entire feature of your page appear or disappear based on a condition, you can simply write something like:

@if (someCondition) {
  <h1>The condition was met. Yeehah!</h1>
}

Straightforward enough: you can just put your desired html output in your block, and it appears or doesn't depending on the condition. And at this point I was in full-on how-hard-can-it-be hubris-mode, cruising for a bruising and headed for a fall. Ok - let's go:

@{
  var documents = @GetComponentPresentationsByTemplate("My Documents CT");
}
@if (documents.Count > 0) {
 <ul class="lookListy"> 
}
@foreach (var cp in documents) {
  @cp.RenderComponentPresentation()
}			          			}
@if (documents.Count > 0) {
 </ul> 
}

... or something similar. Looks reasonable, eh? (OK - maybe with a bit of practice I can get that tidier.) Except it's not. It doesn't compile, or more specific, the C# generated by Razor doesn't compile, and in Tridion, all you see is a nasty message about the wrong number of curly brackets or semicolons or some such. It doesn't really matter much what the error is, because the structure of your code is broken, and the thing it's reporting is further down, and somewhere in the generated code anyway.

Nota Bene: This level of error reporting is reason enough to avoid doing any complex logic in your template. Put it in a class, for goodness' sake!

So what was the problem? It turns out that to put HTML in-line in a Razor block, the tags need to balance, so you can say

<ul>.... <./ul>

, but not an opening

<ul>

without the closing tag.

This is not an issue with razor-mediator-4-tridion per se, but rather one with the way Razor itself works. Still - to do a successful Razor templating implementation in Tridion, you'll almost certainly need to know it. The solution is simple: you just need to wrap your unbalanced tags in a <text/> wrapper, as follows:

@{
  var documents = @GetComponentPresentationsByTemplate("My Documents CT");
}
@if (documents.Count > 0) {
 <text><ul class="lookListy"></text> 
}
@foreach (var cp in documents) {
  @cp.RenderComponentPresentation()
}			          			}
@if (documents.Count > 0) {
 <text></ul></text> 
}

This will now compile correctly, and produce the desired result.

Thanks to the contributors over at http://code.google.com/p/razor-mediator-4-tridion/. It's a great project, and I can see lots of potential for using it in my own work. Much as I'm a fan of XSLT for other uses, in templating its verbosity tends to make people push important code out of view, and well... Dreamweaver syntax ain't pretty either. :-)

EDIT: Thanks to a suggestion by Neil Gibbons (Thanks Neil!) I now realise that if you nest the foreach inside the if (which works for the logic I was trying to achieve), the <ul/> is now seen as 'balanced' and doesn't need the <text.> wrapper. So the problem is less severe than I had thought, but it's still one you need to be aware of.

@{
   var documents = GetComponentPresentationsByTemplate("My Documents CT"); 
   if (documents.Count > 0) {
       <ul class="lookListy">
	 @foreach (var cp in documents) {
	   @cp.RenderComponentPresentation();
       }
       </ul>
    }
  }

Toggling the javascript minification of the Tridion GUI from the powershell

Posted by Dominic Cronin at Nov 12, 2012 11:50 PM |
Filed under: , ,

Most of the time, I use a single Tridion development image for multiple purposes, including whatever time I get to spend researching how to do GUI extensions. When I'm flipping back out of research mode into doing some day-to-day development such as templating, it's better to have the benefit of the javascript minification that I might prefer to switch off while poking around in the guts of Anguilla. So just to make this switch as painless as possible, I've added the following code to my powershell $profile.

function SetGuiMinification($value){
  $filename = 'C:\Program Files (x86)\Tridion\web\WebUI\WebRoot\Configuration\System.config'
  $conf = [xml](gc $filename)
  $conf.Configuration.filters.filter |?{$_.type -like '*JScriptMinifier*'} |%{$_.enabled = $value}
  $conf.Save($filename)
  iisreset
}

function guimin {SetGuiMinification "always"}
function guinomin {SetGuiMinification "never"}

Now I can toggle backwards and forwards simply by typing guimin or guinomin (you may favour different words or spellings!)

Of course, this technique ought to work just as well to manipulate other elements and attributes in the XML files that control a Tridion installation. Perhaps you'd modify it to toggle the CSS minification too (removing the -like clause should do it).

If you have any good ideas for using this technique, please let me know.