Skip to main content

Posts

Showing posts from April, 2012

Workflow GetLastActivityInstance

Writing workflows implies sometimes having to navigate back and forth through the different activities. For example for taking the message of the last Activity, or taking the Assignee of the next Activity. This post gives code samples for retrieving the last Activity Instance. This is the previous Activity Instance that was completed before the current one. /// <summary> /// Return the last activity instance from the current process instance /// </summary> /// <returns></returns> protected ActivityInstance GetLastActivityInstance() {     ActivityInstance activity = CurrentWorkItem.Activity as ActivityInstance ;     ProcessInstance processInstance = activity.Process as ProcessInstance ;     IList < ActivityInstance > activities = new List < ActivityInstance >(processInstance.Activities);     for ( int i = activity.Position - 1; i >= 0; i--) {        ...

Workflow FinishActivity

Where you ever annoyed with the ActivityFinish class? Namely, that second parameter nextAssignee of type Trustee  of the constructor? The constructor signature is the following: public ActivityFinish( string message, Trustee nextAssignee, Session session); So what do I pass as nextAssignee? Figuring that out is not easy... Luckily though, you can simply pass null for the assignee and Tridion will then use the user/group that is defined in the Activity Definition (in the Workflow Visio diagram). What if I want to properly assign a nextAssignee? How do I figure out who the next assignee should be? Well, one way I used in the past was to identify the last manual Activity (thus not automatic, because they are performed by the implicit Tridion user as defined in the SDL Tridion Content Manager MMC snap-in / Workflow settings / Automatic Trustee ID ). Then I used this Trustee for the ActivityFinish. Alternatively, as shown by the code-below, I identify the next...

How to Publish Stuff Programmatically

TOM.NET In TOM.NET (e.g. from an Event System), you can publish an item using the code below: private void Publish( IdentifiableObject item, PublicationTarget publicationTarget,     bool rollBackOnFailure, bool includeComponentLinks) {     IEnumerable < IdentifiableObject > items = new List < IdentifiableObject >() { item };     IEnumerable < PublicationTarget > targets =         new List < PublicationTarget >() { publicationTarget };     PublishInstruction instruction = new PublishInstruction (item.Session)     {         DeployAt = DateTime .Now,         RenderInstruction = new RenderInstruction (item.Session)         {             RenderMode = RenderMode .Publis...

Read Tridion Install Path from Registry Key

Tridion install path is stored in Windows Registry on the machine where Tridion CM is installed. It might be useful sometimes to read this value programmatically -- e.g. when you need to read some configuration files placed in the Tridion_Home\config folder. A little issue might occur when you try to read a Registry key in a Windows 32bit vs 64bit, because these values are stored in different Registry locations. My fellow colleague, Principal Developer Frank van Puffelen (or @puf , for friends :) ), shows a neat way of reading a Registry key irrespective of the code running on a Windows 32 or 64 bit machine: // Opens a registry either from its normal location or from the Wow6432Node and either from HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE. private static RegistryKey FindKeyInRegistry( string registryKey) {      RegistryKey key = Registry .CurrentUser.OpenSubKey(registryKey);      if (key == null )     {      ...

Dreamweaver Double Lookup

We saw in the previous post how to do a double look-up on a TBB parameter in C# code. The same functionality can be achieved doing a double look-up directly in a Dreamweaver (DWT) TBB. The idea behind the double look-up is the same -- I will first read a DWT variable (or expression), then perform the second look-up on the resulting variable (or expression). The syntax in DWT is the following:     @@OuterExpression${InnerExpression}@@ The @@expression@@ notation is equivalent to ${expression} . The whole trick is in the order of evaluation:  ${InnerExpression} is evaluated first, then the @@OuterExpression@@ is evaluated. Example: ImageList is a package item holding an array of Components; Image_0 ,  Image_1 , etc... are package items holding URL values for each item of ImageList; <!-- TemplateBeginRepeat name=" ImageList " -->     <img src=" @@Image_ ${TemplateRepeatIndex} @@ "/> <!-- TemplateEndRepeat --> N...

Templating Parameter Double Lookup

In Tridion templating, double look-up refers to a technique of reading package values two or more times. This is probably most commonly used when reading TBB parameters. For example, let's consider a TBB that takes a parameter called 'inputValue' of type String, which represents a TcmUri. In Template Builder, the template developer can specify a value for 'inputValue' in several ways: hard-code an actual TcmUri, e.g. tcm:1-2 ; use a package item name - e.g. package item named  MyVariable , whose value is the TcmUri; use a Dreamweaver Language Expression - e.g. Component.Fields.BannerImage that resolves to a TcmUri; Hard-Coded Value The look-up in the package is direct: var value = package.GetValue("inputValue"); Package Item Name I need to first look-up the package item, and then take its value. This is a form of double look-up: var paramInputValue = package.GetValue("inputValue"); Item valueItem = package.GetByName(paramInput...

ServiceActivationException after Installing Tridion 2011

I just installed T2011 (after uninstalling T2009SP1) in a Win2003Server SP3 machine, with IIS6. When I try accessing the T2011 CME, I get the error “ /WebUI/Core/Services/Communicator.svc/Invoke failed to execute. STATUS (500): System.ServiceModel.ServiceActivationException ”. The event logs show a bunch of errors like the one below: WebHost failed to process a request. Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/12036987 Exception: System.ServiceModel.ServiceActivationException: The service '/WebUI/Models/TCM54/Services/General.svc' cannot be activated due to an exception during compilation. The exception message is: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.. ---> System.NotSupportedException: Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service. After lo...

Create Embedded Fields Programmatically

During on the my Event Systems, I came across the requirement of creating (and populating) new Embedded Schema fields. To do so, I still used the ItemFields collection, which has a constructor accepting a Schema parameter. This is the one to use, but the counter-intuitive part was to obtain the Embedded Schema. I ended up getting it from the field definition of the 'outer' Schema field. Finally notice that when the Component needs to be saved, the ItemFields collection needs first be saved into the Component's content. ItemFields fields = new ItemFields (component.Content, component.Schema); EmbeddedSchemaField linksField = fields[ "Links" ] as EmbeddedSchemaField ; EmbeddedSchemaFieldDefinition linksFieldDefinition = linksField.Definition as EmbeddedSchemaFieldDefinition ; ItemFields newItemField = new ItemFields (linksFieldDefinition.EmbeddedSchema); (( ComponentLinkField )newItemField[ "Component" ]).Value = anotherComponent; ...

Passing PageUri to a DCP for Dynamic Linking

We should all know by now that passing an empty (aka Null TcmUri) as PageUri when resolving a Component Link is very bad practice. The reason -- this kind of link resolving is not cached. So, in case you are using a Content Delivery DB, you will make a trip to the DB for every single Component Link resolving. I have written an older article available here on SDLTridionWorld , about solving these issues, but that's about old school templating. This post presents the mechanism to use when writing Compound Templates. So, I have a DWT TBB that generates some output for an RTF field. Something like @@Component.Fields.Paragraph@@ . I have some ComponentLinks in the RTF field. The templates runs on a DCP and it generates a TCDL link like this: <tcdl:Link type="Component" origin="tcm:0-0-0" destination="tcm:37-968" templateURI="tcm:0-0-0" linkAttributes="" textOnFail="true" addAnchor="false" variantId...

What Actually Gets Published?

This post describes in short the resolving mechanism when a certain item is being published. This is also known as "Where Used" link resolving (or propagation) and can be defined as follows: " when publishing an item, all items using this item will be published too, but only if they are already published ". In other words, when publishing an item, the "Where Used" list of that item (i.e. the items using that item) will be published as well. a) If DCP is on a Page, and you publish the Page, then the following gets published: - the Page; - all DCPs on the Page; - the Component in each DCP [which continues in point b) further]; b) If publishing a Component, the following gets published: - all DCPs made out of that Component with each Dynamic CT on the same Schema; - all _linking-to_ Components (e.g. Comp A links to Comp B; if Comp B is published, then Comp A is published too; however, links to Comp A don’t g...

Demystifying Tridion Code Generation

During publishing Tridion generates (or better said transforms) some code, depending on certain settings, such as: Publication Target Target Language ; Component Template Output Format ; Deployer config TCDLEngine Properties ; Let's see some details about these parameters and how they work with each other. Publication Target The Target Language specifies the destination language that the Deployer should transform any TCDL ( Tridion Content Delivery Language ) code it finds in the Transport Package. You can think about this language as the ' website language ' or the Tridion code that is generated by a Page Template (we will tackle the Component Template code in the next section). Common values for Target Language are: ASP.NET - select this if you are publishing to a .NET website and the Deployer should transform to .NET code; Generated code sample: < tridion : ComponentPresentation runat ="server" PageURI ="tcm:4-5-64" Compon...

Publishing CSS or JS as Multimedia Components?

Let me start by saying that I am a strong believer that handling, uploading or publishing CSS or JS files as Multimedia Components is bad practice . At the same time I was recently surprised that opinions are actually quite different on the topic. There are people who don't always agree with me, shocker!!! So I guess the point of this post is just to present the advantages/disadvantages of the two methods and see which you like best. Make that one best practice :) Multimedia Components In this approach, CSS or JS files are uploaded into Tridion as MMComponents based on a MMSchema. This is the default way the Dreamweaver mediator handles references to CSS or JS from an HTML (.dwt) document. Advantages: speed - easy to upload into Tridion, without having to create additional items like Schemas, Components, CTs, PTs, Pages; easy to understand - developers with little Tridion experience understand this approach easier; out-of-the-box - this is the default way the Dreamwe...

Referencing Image Variants from Dreamweaver Templates

OK, so you've written your Resize Image TBB that publishes a variant image... But now you need a reference (e.g. the URL) of this variant in DWT. How would I get that? The first thing I tried, in my DW TBB, was to reference the image variant using the attribute tridion:variantId . How cool it would be that by just referencing the image TcmUri and variantId in DWT to actually have that resolved and replaced by the Resolve Links default TBB. Something like this: <img src="tcm:1-2" tridion:variantId="thumbnail"/> Well, it doesn't work! The TBB Resolve Links doesn't know about attribute tridion:variantId on an img element. So, I told myself "I will write My Own Resolve Links TBB" and I started investigating... What I tried was retrieving the image variant from the package (lookup by name or Tcmuri), then identify the one I needed by matching on the variantId . Well, that doesn't work either! It seems that there is only one...