Friday, December 29, 2017

What's New in SDL WorldServer 11

Local Language Content is growing in demand day by day and it is one of the primary focus areas of Marketers today. Various surveys show, how the local language content helped companies to get more customers and contributed to the growth of the business eventually. One shouldn’t be surprised why Translation Management System is a really important tool of CXM strategy of an Enterprise today.

SDL WorldServer:


SDL WorldServer is the leading translation management system in the industry. Over one hundred of the top global companies depend on SDL WorldServer to optimize their translation programs.

WorldServer is an advanced tool that enables you to transform manual, disparate translation processes into a centralized, fully administered program. With WorldServer, you can adopt a flexible enterprise-class translation management system that automates translation tasks and greatly reduces the costs of supporting large volumes of local language content.

Core to SDL WorldServer is a workflow based process automation engine that drives all translation project activities. You can easily configure the workflow so that, for example, the process for translating marketing material is different from that for translating very technical documentation.

New features & benefits in Version 11:


Recently in November 2017, the latest version 11.3 of the SDL WorldServer is released. Other than supporting technology upgrades, below are the key new features introduced in the version 11, adding value over V10.4: 

UI enhancements:

The new version has significant rewrite of the User Interface layer to provide modern & efficient User Experience for all users.

Below are the main features of the new UI:
  • New UI paradigm aligned with SDL’s Convergence strategy.
  • Initial Focus on Project Management UX and Efficiency.
  • Platform for delivering usability improvements.
  • Modern, supportable UI components.
  • New REST-based API is used under the hood.


Performance & Scalability:

1. System Improvements for Scalability & Agility:
  • Database Transactions optimizations to eliminate deadlocks and enhance efficiency and scalability. The version Supports SQL Server 2016 as well.
  • Monitoring & Troubleshooting by the new diagnostic tools to identify and address deadlocking database transactions.
  • Automated Task Handling by sequencing and distributing automated tasks to prevent time consuming tasks from slowing down the system as a whole.
  • Translatable Content Handling is improved by:
             o Updated file filters for MS Office file types.
             o New server-friendly file types for RTF and Excel

2. Cloud Improvements:
  • Value add Security packages like encryption, IDS/IPS, compliance, vulnerability scanning, etc.
  • Next Generation Database Platform with increased availability, scalability, manageability and security.
  • Further automation of deployment/upgrades and other maintenance tasks.
  • Modernization of Cloud Delivery Platforms including new hosting providers, new data centres, more modern services and infrastructure.

SDL Language Cloud integration:

Starting with this release, machine translation in WorldServer can also be performed by SDL Language Cloud, via the new Language Cloud machine translation (MT) adapter. Once the adapter is configured, the translation can be done automatically in Worldserver using SDL Language cloud.
The process of setting the adapter is quite straight forward as demonstrated here.

Applet replacement:

Because browsers are reducing or eliminating support for the Java Plug-in, it is wise to consider migrating existing Java applets to something like Java Web Start, which uses the Java Network Launching Protocol (JNLP) to download and run an application locally.

From the release 11.1, SDL have started the procedure of migrating the WorldServer features that use Java applets to JNLP. As a result, user can now access the Explorer page from all supported browsers. User can modify the use of Java applet or JNLP by configuring the parameter applet.display.option=<available values are applet, jnlp, and browser>, in general.properties. SDL recommend using the browser option, which will make the browser choose whether the Java applet or JNLP is used to open the Explorer page.

Next Gen Online Editor:

Online editor is one of the most important feature introduced in the V11. It is an Add-On Components to the GUI and can be configured to be used in workflows by Translators and/or Reviewers.
With this, Translators and Reviewers can perform many tasks including translation & review from anywhere online in browser without having to install Studio. Though Trados Studio and WS Browser Workbench remain alternate options.

REST APIs:

A rich REST API is available now to interact with the WorldServer. The SDL WorldServer 11 API is based on modern standards (REST & JSON) and has been designed to be:
  • Highly secure: the entire WorldServer 11 UI is built on top of the new, radically improved API.
  • Standardized and easy to use: it uses the standard HTTP Verbs (POST/PUT/GET/DELETE).
  • More easily integrated.
  • Highly functional, with:
          o Batching — do more with less
          o Filtering & Search — find the right data
          o Partial record retrieval — retrieve only the fields you need, avoiding over-verbosity.

The API Documentation can be found on the server by visiting <root_server>/<ws-api>/docs/ws-api-doc-v1.html (for example, http://<server_name>:<port_number>/<ws-api>/docs/ws-api-doc-v1.html).



Thursday, December 28, 2017

Alchemy | What do you want to extend ?

  
In one of my previous blogs, I talked about the Five Basic Things you should know before developing a Alchemy Plugin. One of the most important thing listed there is, "What do you want to extend?" in Tridion GUI. The answer to this question would lead you to the Classes in Alchemy Framework,
you would have to extend in the plugin code. You can term them as Extension Points as well.

Tridion provides some extension points/areas out of the box. In Alchemy Framework you would get all those extension points as Base Classes, you simply need to extend those classes according to your plugin need. Let's talk about the Extension Points one by one.

1. Context Menu Extension:

A Context Menu appears once a user right clicks on a Item in Tridion GUI. So if you want to add an entry in the Context Menu, you would have to extend "ContextMenuExtension" class in your plugin code.
Title Translator plugin is a really good example of Context Menu Extension, The code for the plugin can be found here.

2. Command Extension:

Tridion's Anguilla Framework exposes many commands like Open, Save, Localize etc. Which are executed on respective events in the GUI. If you want to override the behavior of a command, all you need is to extend "CommandExtension" class in your plugin's code.
For example, if you want to perform some action when user saves an item, you would need to create a Alchemy Plugin by extending the class "CommandExtension".

We have a Plugin named Localize Commenter which extends this extension point, where a custom popup appears when a "Localize" command is executed.  The code for the plugin could be found here for reference.

3. Extended Area Extension:

Extended Area Extension
If your requirement is to extend a existing view, you might want to have a look at the extended areas extensibility. For example, if someone wants to add a additional check in fields details in schema design, you might need to create a plugin extending "ExtendedAreaExtension" class. I don't have any real plugin for reference, so attaching the image to give you an idea.




4. Extension Group:

So, if you don't find a suitable extension point for your plugin idea or requirement. The Extension Group extension could be your best bet. Basically this extension allows you to add your custom resources (JS, CSS, Images etc) to the different views in the GUI. These resources can then interact with the HTML and Tridion UI Core (using Anguilla framework) to produce desired results.

One good example of this type of plugin is Publication Panel Search. It places a search box above the Publication List in the left-hand panel. Users can simply start typing into the text box and Publications with the title containing the entered text will be filtered. The full code for the plugin can be referenced from here.

5. Ribbon Toolbar Extension:

As it's name suggests, this extension point is to extend the Ribbon Toolbar at the top. With this one can add buttons and manage groups in the toolbar. To achieve this all you need to extend the "RibbonToolbarExtension" class and use it's members accordingly, while coding the plugin.

There are many plugins of this type available on the Alchemy Web Store, one easy pick could be Go To Location. This plugin adds a Ribbon Tool Bar Button 'Go To Location' to the Repository Local Item views, on clicking the button user is redirected to the location of the item. The code for this plugin can be found here.

6. Tab Page Extension:

If a Tridion item is opened in explorer, there would be tabs like General, Source, Info etc. To add a custom tab to the view, in the plugin's code one has to extend the class "TabPageExtension" and use it's members accordingly.

There is again this plugin Localize Commenter which extends this extension point. The plugin adds a tab "Localize Comments" in the item's view, where localize comments can be viewed and edited. The code for the plugin can be found here for reference.

Saturday, December 16, 2017

Localize Commenter | Yet Another Alchemy Plugin

Localization of content is one of the most important feature of a Content Management System. Over the years CMS vendors put a lot of emphasis on making content localization easy and user friendly. If we talk about SDL Tridion, its simply a click and user can localize an item and update it with local content. It is really easy and user friendly, But there is no way one can record the "Reason" to localize the item. So with the passing time no body remembers why the item was localized?

To address this issue, This plugin named "Localize Commenter" is developed. This available on Alchemy Web Store and can be downloaded from here.

The Plugin forces user to add Comments while localizing an Item in Tridion GUI. These Comments could be be viewed and Edited in a Tab inside Item View. Technically, The plugin stores the Comments inside App Data of the Item and doesn't maintain the history of the comments, so once comments are updated the last comments will be deleted forever.

The code for the plugin is available on Github. So if you look at the code, the plugin consists of three extension points as below:

1. Command Extension:

The first requirement was "when user clicks "Localize" from the context menu of an item, the plugin would open a dialog to enter the localize comments" as below:


To achieve this, a Command Extension is implemented which simply extends the Localize command using Anguilla Framework (Code reference "LocalizeCommenterCommandExtension.cs"). This extension simply open a popup "LocalizeCommenterPopUp.aspx" , and cancels the original Localize command.

"LocalizeCommenterPopUp.aspx" page is simple .aspx page, which has a text area, localize button and a cancel button. After entering the comments in the text area when user hit the localize button,  item gets localized and comments gets saved to application data of the item.

2. Extension Group:

The second requirement was "when a user opens a shared item by choosing the option 'Localize this item and open it in edit mode',  the plugin would open a popup to enter the comments" as below:


For this, a "ExtensionGroup" extension is implemented which simply extends this "Choose an Option" popup by extending "Tridion.Web.UI.Editors.CME.Views.Popups.SharedItemOptions" resource using Anguilla Framework (Code Reference "SharedItemOptionsPopUpExtension.cs"). This simply overrides the "_onOkButtonClicked" event of "Choose an Option" popup and open another popup "LocalizeCommenterPopUp.aspx" to enter the comments, when the "OK" button is clicked.


3. Tab Page Extension:

The third requirement was "Once the item is localized after adding the comments, There should be a way to check and update the saved comments". The plugin shows the saved comments in a "Localize Comments" tab when the item is opened.

To achieve this, a "TabPageExtenstion" extension is implemented (Code Reference "LocalizeCommenterTabPage.cs"). The extension creates a tab named "Localize Comments" in item's view and shows a user control "LocalizeCommenterTab.ascx" inside this. Inside the control, functionality to view/update the comments is implemented. 


Please check the code for more details, This plugin is pretty good example of having multiple extensions in a single plugin. If you have any questions, please ask on the post.

Thursday, October 26, 2017

Forcing Workflow on Templates (Design Items) in Tridion

The main purpose of  Tridion Workflow is to audit content before it is published to a particular environment, but it is also important to audit the design changes before making those available for a end user on a particular environment. Without proper auditing wrong version of the layouts (and possibly JS functionality) could make all the way to Live application and can have all sorts of user experience issues.





Importance of Workflow Enforcement on Tridion Items:

 

When a tridion item is updated outside of the workflow or a new item created, item was set to approval status 'undefined'. With this 'undefined' approval status there was no restriction on publishing those items at all, means the item (content/template) which was yet to be approved by workflow process could be published.

To make sure any unaudited item (content/template) doesn't get published. Tridion provides OOB functionality to Enforce Workflow on Components and Templates.

In one of my previous blogs, I explained how to force workflow on Components. Here I am going to explain how you can force workflow on Templates (TBBs, CTs and PTs).


Forcing Workflow on Templates:


1. Enable workflow on the publication:
Before forcing workflow on the items, you should always enable the workflow on that particular publication otherwise new and updated items would be waiting forever for a workflow to be enforced, as user would not be able to trigger a workflow process on the templates.

To do so, open publication properties and inside workflow tab check the checkbox "Enable Workflow Process Associations in Shared Schemas and Structure Groups" and save the publication properties.









2. Force the workflow on design items:
To force workflow, open publication properties and inside workflow tab check the checkbox "Any changes made to a Template in this Publication require approval by a Bundle Workflow Process" and save the publication properties.










Once the workflow enforcement on templates is set on the publication, Now if you updates/creates template (or TBB) outside of workflow, Instead of being checked-in and available for use, a minor version of the template will be created in "Waiting for Workflow" state. To use this version, you must add it to a bundle and start the workflow on it. Once the workflow is finished, the minor version is converted to a major version and is ready for use.

Thursday, October 12, 2017

Five Basic Things you should know before developing a Alchemy Plugin



Alchemy for Tridion is getting popularity by every day passing. More and more plugins are being submitted to Alchemy Web Store. I have developed few and it's really a fun. So if you want to give it a try go ahead, all you need to do is:

1. Install the Alchemy on your DEV CMS Machine.

2. Get the Alchemy development framework to visual studio using Nuget Package or VS Pack.




Now when you are all set to develop a Alchemy Plugin from your idea. Ask the below questions to yourself and note the answers:
  1. What does it do?
  2. What do you want to extend?
  3. Where to show your extension?
  4. When to show your extension?
  5. What resources you need to have in your extension?


What does it do?

The answer to this question will help you with
1. You can copy and paste the answer to the description element value of the "a4t.xml" file in your visual studio solution.
2. This will help you identify the possible conflicts with existing OOB GUI/Functionality. Which is quite important consideration before developing a plugin.


What do you want to extend?

So Tridion provides some extension points/areas OOB. In Alchemy Framework you would have all those extension points as Base Classes as below: 


  • CommandExtension
  • ContextMenuExtension
  • ExtendedAreaExtension
  • ExtensionGroup
  • RibbonToolbarExtension
  • TabPageExtension

You have to answer which extension point(or points), you want to extend. And based on this answer, you would create your Extension class by extending one of the above listed classes.

Where to show your extension?
So other than command extension, you need to tell Alchemy where you want to show the extension. This is really a important question as you need to make sure your extension doesn't break the existing GUI and not in conflict with another Plugin/Extension.

When to show your extension?
So there could be conditions when to show (or execute in case of command extension) the Extension. For example, a particular Extension could be available for any particular User Group. So if you have any condition like it, you would have to take care of this during the development. There are different ways to control it for different type of Extensions.

What resources you need to have in your extension?
You could have additional resources to support your extension like JS, CSS, ASPX ans ASCX files. You need to identify the resources and the place to put those. Alchemy Framework has a very specific structured way to organize those files.

I will cover all above points in detail in my coming blogs. I hope this high level information helps.    

Wednesday, September 27, 2017

Workflow, Core Service and Tridion Crashing Blues


The Tridion Workflow is basically used to audit the content before publishing out to specific environment. It is really a good module of Tridion CMS, little bit underestimated in my opinion though.

Recently, I come across a issue where Tridion was going unresponsive, when we had some 30+ workflow process ruining simultaneously. It took us some good time to figure out the root cause of the issue. My intention of writing this blog to save your investigation time in case you face the same issue.


The issue:
The Tridion gets unresponsive when there is load on the CMS server in the form of Workflow Processes.

The Root Cause:
While setting a Tridion CMS, one has to configure the Maximum Concurrent Core Service Instances allowed before Core Service Host gets throttled. If the number of Core Service Instances goes beyond that limit, the Core Service Host Service gets throttled and become unresponsive. In our case Workflow Processes were creating those Core Service Instances.

In our configuration settings, we had the value set at the default minimum value (which was 100); not the recommended value (100 x {No. of Cores}). So this minimum value 100 was getting crossed easily by the Core service Instances when the load was high and so Tridion was getting unresponsive.

These configuration settings are listed below and can be found in the files as under:

<serviceThrottling maxConcurrentSessions="100" maxConcurrentCalls="16" />

*The default value for the Maximum Concurrent Instances is { maxConcurrentSessions + maxConcurrentCalls}

1. {TridionDir}\webservices\web.config
2. {TridionDir}\bin\TcmServiceHost.exe.config

As per recommendation the default values should multiplied by no. of cores on the server.

Workflow Connection to the Issue:
When an auto External Activity in a workflow process starts, it automatically gets an instance of a “Ready Made” Core Service Client and it does not closed/disposed once the activity is finished (Proved) rather it is cleaned/closed when garbage collection happens later by the system (Yet to confirm with SDL). The more Workflow Processes result in more auto External Activities and so more concurrent Core Service Clients. Once the max allowed limit for Core Service instances is crossed, the CMS goes throttled and become unresponsive.

The Fix:
We had to increase the maximum allowed limit for load in configuration files on CMS. To do so, we increased the throttling attributes for Core Service to allow more concurrent Core Service instances as below (The configuration could be found in the files listed above already):

<serviceThrottling maxConcurrentSessions="100*{No. of Cores}" maxConcurrentCalls="16*{No. of Cores}" />

*Where {No. of Cores} is the number of cores available on the CMS Server.




I hope, this helps someone someday :)


Friday, June 2, 2017

Go To Location | Alchemy Plugin for SDL Web

At SDL Web Dev Summit 2017 in India, I got this opportunity to show & tell on "how to create a Alchemy Plugin in 30 mins". And I choose to build this simple "GoToLocation" Alchemy Plugin there.

This plugin adds a Ribbon Tool Bar Button 'Go To Location' to the Repository Local Items Views including Page, Component, Schema, Component Templates, Page Templates and Template Building Blocks. On clicking the button SDL Web redirects the user to the location of the item.

This plugin is useful in the situations when a user wants to navigate to the Item's location form the Item's View.

In case you missed the event, lets revisit the plugin again. So before we begin, get the plugin's code from here so that we both are on the same page.

Facts about the plugin:
  1. It is a Ribbon Toolbar Extension, which places a "Go To Location" button in the ribbon.
  2. It will be applicable to following views:
    • Component
    • Page
    • Schema
    • Page Templates
    • Component Templates
    • Template Building Blocks
  3. On clicking the button, a Command fires to take the control to the item's location.
  4. It needs to have following resources (Resource Group) available in Tridion
    • Image - to be applied on the button
    • CSS File - to define styling on the extension button
    • Command JS File - to define the command to be fired on button click

Lets visit the code against the above points:
  1. Open the file "Config\GoToLocationExtension.cs". you would notice that the class is extended with the base class "RibbonToolbarExtension". Doing this you instruct Alchemy Framework that your extension is a Ribbon Toolbar Extension.
  2. In the same file you would see the lines like Apply.ToView(Constants.Views.{ViewName}). The code is to apply the extension on different views.
  3. We always define the Tridion Commands in JS files and place it inside a fixed folder structure "Static/Commands". You can see we have "GotoLocationCommands.js" in there to define our command. In execute method of the command, we simply get the "GoTo" command defined in Anguilla Framework and execute it on selected item.
  4. Resources are generally supportive files needed in Tridion for your extension. These files are organized in a fixed structure in the project inside the "Static" folder.
    • Image: To apply an image, we need to add the image in the project inside the folder "Static/Images" so that it is available to use.
    • CSS File: This file contains all the styling we need to add to our extension and sits in "Static/Styles" folder. In this case we just want a background image for the ribbon bar button as styling. If you notice in the css file, we are applying the image on a element with the id "RibbonToolbarGoToLocationButton". The id is nothing but the Assign Id of the extension (defined in "GoToLocationExtension.cs" file), which ends up as a HTML element id for the extension. 
    • Command JS File:  The file is located at "Static/Commands" and contains the command as we mentioned in point 3.
Now when we created different pieces we need for the functioning of our extension, We need to instruct Alchemy Framework; what is what and how these are inter connected?
  1. Alchemy Framework needs to know about the commands your extension have and to define it, we create a class derived from "CommandSet" base class. The class "GoToLocationExtension.cs" could be spotted under "Config" folder, having the command added (defined in the Command JS File, the name must match)
  2. We must tell Alchemy, which resources are going to use for the extension and to define it, we create another class derived from "ResourceGroup" base class. This class adds all the Resource Files, Command Sets and other dependencies needed for the extension. The class can be found at "Config/GoToLocationResouceGroup.cs".
  3. Lastly tell Alchemy that the extension is dependent on the Resource Group we just created. To do so, add the line Dependencies.Add<GoToLocationResouceGroup>() to the extension class "Config\GoToLocationExtension.cs".
And that's it. All other properties in the code files are quite self explanatory. 
Now build the project, you get your .A4T alchemy file for the extension. yay!



Monday, December 26, 2016

Edit Templates From Page | Alchemy Plugin

SDL Developers India Community organized a professionals meet this year in New Delhi and I was fortunate to join the event. I met some really nice guys from the community there and had a good time. I also spoke on Alchemy along with Robert Curtelle and after finishing the session, this guy Tejas came to me with this idea of the plugin.

He said, as a Tridion developer when he found a rendering bug on a webpage (published from SDL WEB), he used to do the following:
1. Navigate to the page in Tridion.
2. See which templates were used.
3. Memorize the Name or TcmId of the template.
4. Navigate to the template to open it.
5. Check the TBBs used in the template to identify/fix the issue.

He asked me it would be really helpful, if we could build a plugin which gives links/buttons to Edit the templates directly from the page. With this we could eliminate the steps 2, 3, 4 from the process above. I really liked the Idea and almost after a year I manged to build the plugin (Yeah, I know I am lazy :) )

What it does?:

Well, it is one of the simplest plugins you would have. It simply places edit buttons in form of the templates used on the page. User can simply click the buttons to Open/Edit the template.
Page Template Edit Button











Let's build it once again:


I've already shared the code for the plugin on GitHub. You can have a look at the code in detail after downloading it but let's discuss it briefly here.
In technical terms, we want to build a "ExtensionGroup" GUI Extension using Alchemy, which has group of resource files, to be targeted to the Page View ("Tridion.Web.UI.Editors.CME.Views.Page").
So after creating a project using the A4T template in Visual Studio, I created two classes:

1. EditTemplatesFromPageResourceGroup (Extending from ResourceGroup base class)

2. EditTemplatesFromPageExtensionGroup (Extending from ExtensionGroup base class)



EditTemplatesFromPageResourceGroup


As the comment inside the code says, this code simply adds "EditTemplatesFromPageResourceGroup" Resource Group as an Extension to extend the resource "Tridion.Web.UI.Editors.CME.Views.Page". That means all the resource files referenced in the class "EditTemplatesFromPageResourceGroup" will be available on the Page.

EditTemplatesFromPageResourceGroup




















This class represents a Resource Group, we want to add for the extension.
From line 17 to 19 we are adding JS and CSS files needed.
Line 21 adds a Web API Proxy in case we want to interact with CMS using Web API Controller, Though we are not using it in this version but added it for future versions.
Line 23 adds JQuery as a dependency. With this we can have JQuery  available in our JS files. If you look at the JS code, you will see we are creating JQuery object something like

$JQ = Alchemy.library("jQuery");

Okay, lets talk about the resource files used in the Resource Group . It has the following resource files:

1. PageTemplateEditLink.js
  This JS file is responsible to render the Page Template Edit Button. If you look at the code, it simply
  1. Create a HTML Element for the button
  2. Insert it beside the Page Template dropdown
  3. Add a "click" event handler function to the button, which runs the following JS code
var pageTemplateId = page.getPageTemplateId();
var s = new Tridion.Cme.Selection();
s.addItem(pageTemplateId);
$commands.executeCommand("Open", s);

The code gets the current Page Template from the Page object and fires a "Open" command on it using Anguilla framework.

2. ComponentTemplateEditLink.js
This JS file is responsible to render the Component Template Edit Button/s. What is does:
  1. Create a HTML Element for the button
  2. Insert it beside the Component Template dropdown in Component Presentations Tab
  3. Add a "click" event handler method to the button as below
// Get the selected Component template from the dropdown anguilla object
var ctId = ddl.getValue();
// Execute the open command
var s = new Tridion.Cme.Selection();
s.addItem(ctId);
$commands.executeCommand("Open", s);

The code gets the current Component Template from the dropdown object and fires a "Open" command on it using Anguilla framework.

3. EditTemplatesFromPage.css
This file contains all the css styles used for the Edit Buttons.


After updating a4t.xml file with the name and description, now we are all set to build our plugin and after a successful build we will get the magic A4T file, which can be installed to Tridion SDL Web.

Again, I have shared the plugin code on GitHub you can download it if you want. In case you have any questions, feel free to contact or write comments. 



Friday, October 21, 2016

Forcing Workflow on the Components | Things you should know

We implemented workflow using bundles with Tridion version 2013 SP1 HR1. Customer really liked the overall functionality but when a component updated outside of the workflow or a new component created, component was set to approval status 'undefined'. With this 'undefined' approval status there was no restriction on publishing those components at all, means the content which was yet to be approved by workflow process could be published. Certainly we didn't want this as this takes away one of the main purposes 'Content Auditing' of having the workflow.

So we needed some way to mitigate this risk and force the workflow on the items before they are set to publish.

Tridion provides a OOB option to force workflow on items, for this use the checkbox “Any changes made to a Component based on this Schema require approval by a Bundle Workflow Process” in the Component Schema as shown below:

enter image description here

How does it work in concept 

If the check box is checked in the schema, components based on the Schema cannot be checked-in except by workflow. The process would be, you add the items to a Bundle and when you are ready for all of the items inside to go through workflow then Start Workflow on that Bundle.
If someone updates/creates components outside of workflow, Instead of being checked-in, the components will be "Waiting for Workflow" before you add it to a Bundle and start the workflow on it. Components could be unlocked, so other people can continue editing it, with the condition that they need to take over all previous changes too (so if they Undo Checkout, they throw away all changes, not just their own). The CME and Experience Manager will prompt you to "take ownership" when you attempt to edit such a component, The workflow doesn’t give that prompt and assign the previous changes to the current user of the activity.

Porting content using Content Porter tool:

The content porting remains the same in principal with this workflow enforcement, below are few points worth highlighting:
a. Components could be updated/created outside of workflow for the first time, a  minor version will be created with the updates and then components will be locked and waiting for workflow. (Further updates to the components are possible manually but not with the content porter. In manual case user will have to “Take Ownership” of the previous updates).

b. Subsequent updates could only be made If the components are in workflow, the workflow activity is assigned to the user doing the porting. OR once the items have gone through the workflow (components have latest major versions).

Translation:

We are supporting translation inside workflow and we faced a issue related to translation after enabling the workflow enforcement as asked here.

So we had a “Send For Translation” workflow activity to send the content for translation. This activity creates a translation job of type “Push” and sends components for translation. when the translation job is sent, the component is localized and checked-out in target publications. When the translation is retrieved by the translation management system it's checked back in. (This works like this when we don't force the workflow in the components).
But after forcing Bundle Workflow Process on Components using the checkbox in the schema, Once translation is complete, the components are NOT localized with the local content in the target publication.

I guess, this could be because when TMS tries to localize and update the component, it can’t because Tridion expects the component to be locked by a “Bundle Workflow Process”. And so the component is not localized and remains untranslated.

Solution:
This issue is with 2013 sp1 and as it mentioned in one of the answers, there is a a hotfix for this issue "TT88491".
But there are workaround for this issue without this hotfix.
  1. Localize the schema at local publication level and uncheck the checkbox.
  2. Disable workflow for local Publication.
I've not tested it but expert says that this issue is fixed in web 8.



That's it chaps, it's really a cool feature do try it.

Friday, September 23, 2016

Items Panel Search Alchemy Plugin

Here is another Alchemy plugin called Items Panel Search, which is now available on Alchemy Web Store. It is inspired by another plugin called Publication Panel Search, publication panel search plugin operates on publications list but this plugin on items list in the right panel. It places a search box over items list to search or filter items. User types some text and the items list gets filtered on every key press and shows the items containing the string.

Also, the plugin preserves the search value and the search results if user open an item from the list or does the sorting. User can reset the search by clicking the refresh button at the top of the list.

Other than search for a particular item in a long item list, this plugin could be useful in situations when someone wants to operate on a set of items having a common string in title of the items. As shown in below image, all the items having “Articles” in titles are filtered.



This plugin gives users two search options, titles only and all information presented in the list. By default it searches on the titles of the items, if user want to search for all information shown, he can enable it going to plugin configuration and set the value for “SearchAllInformation” to true.







In technical term it is a GUI extension of type Resource Extension Group added to the Dashboard View. It simply contains a JS file as a resource, that is responsible to put the search box on the top of FilteredListControl and all the functionality included.

To see the plugin code please visit this Github link.

Feel free to contact if you have any questions or suggestions regarding this plugin.

Sunday, May 29, 2016

Title Translator | Alchemy Plugin for Tridion

I worked on a Tridion implementation for a client managing huge local content for their websites. One could imagine that local content is hardly anything to do with a developer, but he could be wrong. So at that client, with the content inside the localized components, the title of the items were also in local languages (at many places), specifically they had tons of local taxonomies with the local language titles. Now if any issues reported for a localized website, it was a nightmare for the developers to dig in to the content while investigating that issue because we developers knew only English language.

Few weeks ago, while looking at some of old work for that client that I remembered those days and that issue. So I decided to create a Alchemy Plugin called called Title Translator to address that issue, you can follow the link to Alchemy Web Store and download it from there.
This is really a simple plugin which uses SDL Translation API in background, all you need to do is get a SDL Translation API key, set the key in Plugin Configuration and you are ready to go. In the coming versions, I will try to include the support for Microsoft and Google translation as well.

To use the plugin, simply right click on a title in your CMS Filtered Item list or left-hand​ navigation panel and select 'Translate Title'. The updated title will show in the notification bar.












On the Technical side, This plugin is created using Alchemy Framework. The idea was pretty simple, create a context menu extension and on clicking it fire a command to show the translated title in notification bar.

The Code for the Plugin can be found here on Github. This basically have following building blocks:

  • TranslatorContextMenuExtension: This class holds information about your context menu extension. Other than specifying name and id, below are the important pieces of info it has:  
    • The order of your extension in the context menu.
    • Associated command to the context menu extension.
    • Dependent resource groups.
    • Which view, the extension applies to, In this extesnsion it applies to "DashboardView".
  • TranslatorCommandSet: The class is all about creating a command set from the commands specified in the JS files. We have only one command called "translate" and it is add to the commandset.
  • TranslatorResourceGroup: This class is used to tell alchemy, which resources (files/CommandSets) are you using in your extension. We have just one JS file named "TranslatorCommand.js" and one command set, so adding those in there.
  • TranslatorCommand.js file: This file holds the command code, which fires once "Translate Title" in context menu is clicked. The code basically sends the request to the SDL Machine Translation Service and gets back the translated title as an response and shows it in notification bar.
That's it chaps, go use it. And yeah, feel free to leave comments, questions, report bugs, improvements, pretty much anything related to it.


Thanks.

Wednesday, January 6, 2016

Tridion Custom Tools Example Projects – Event Handler

In the blogpost series of Tridion Custom Tools Example Projects, this blog covers the Event Handler Extension. The Example Code Project could be found here on GIT. I've also shared the Visual Studio Extension here, If you want to install the project template in visual studio for event handler.

An Event Handler is a piece of functionality that is triggered when a certain type of event happens to a certain Content Manager item, for example when a Component being saved.

In Technical terms, It is a .NET assembly that uses the Event System to hook into events occurring in the Content Manager.The Event System is part of the TOM.NET (.NET Tridion Object Model) API. 


To create an Event Handler, create a class that extends Tridion.ContentManager.Extensibility.TcmExtension. You then need to compile your Event Handler into an assembly (DLL) and register it.

Procedure (Copied From SDL Documentation)

  1. In Visual Studio, create a class that extends Tridion.ContentManager.Extensibility.TcmExtension. This class must have a unique class attribute, say,[TcmExtension("MyUniqueEventHandlerExtension")].
  2. In the constructor of this class, execute code that subscribes to one or more events using the following methods:
SubscribeAsync
Subscribe asynchronously to an event. Select this method if your Event Handler code does not affect the data being handled in the Content Manager. For example, if your Event Handler saves data to a backup system or a log file, you can select this method.
Subscribe
Subscribe synchronously to an event. Select this method if your Event Handler code changes the data being handled. For example, if your Event Handler analyzes a Component and then adds metadata to it, ensure that you select this method.
Both methods have the following signatures:
Subscribe<TSubject, TEvent>(TcmEventHandler<TSubject, TEvent> eventHandler, EventPhases phases, EventSubscriptionOrder order)
SubscribeAsync<TSubject, TEvent>(TcmEventHandler<TSubject, TEvent> eventHandler, EventPhases phases, EventSubscriptionOrder order)
where the parameters mean the following:
TSubject (type parameter)
This is the type(s) of the object you are checking events for. This can be any item of class Tridion.ContentManager.IdentifiableObject or any of its subclasses, which includes any kind of content item (such as Component, Schema or Target Group), organizational item (such as Folder or Structure Group) or system-wide object (such as User or Group).
TEvent (type parameter)
This indicates the type(s) of event that trigger this code if applied to an item of the object type specified in TSubject. This can be any event of classTridion.ContentManager.Extensibility.TcmEventArgs or any of its subclasses.
TcmEventHandler<TSubject, TEvent> eventHandler
The name of the method that contains the code you want to be triggered when the event occurs. This method should be contained in the same class and should have parameters that are the same as the type parameters of this Subscribe or SubscribeAsync method.
EventPhases phases
The exact moment during the event at which the event code should be triggered. Note that this parameter is an enum with FlagsAttribute, meaning that you can select multiple moments, which in turn means that a single event could trigger the same code multiple times.
EventSubscriptionOrder order
This optional parameter specifies when the event code should be executed if the same event triggers multiple Event Handlers.
  1. Now, in the same class, implement your event code in a method with the name specified in the eventHandler parameter of the Subscribe or SubscribeAsync method. In this method, you can perform any action you wish, including any type of querying, modification or other manipulation of items in the Content Manager. Include any namespace you need to access these items.
When you write this code, note the following:
    • You can make changes to the members of the TEvent parameter (the members are different depending on the event type) by exchanging information between Event Handlers.
    • When executed, the code you write may result in other event code being triggered.
    • From your event handling method, you can identify the specific user who triggered the event through the Session property of your first parameter of type <TSubject>. For example, if your method has a signature HandlerForSave(Component subject, SaveEventArgs args, EventPhases phase), get the name of the user by checking subject.Session.User.Title.
  1. Once you are satisfied with your code, shut down the following services on your Content Manager server:
    • IIS
    • Any Tridion-related COM+ services
    • If your code is related to publishing, the Publisher service of SDL Tridion
  2. Compile your class to a .NET assembly.
Note: If your event code contains a bug that raises an exception, it can cause the event that triggered it to hang. Especially if your event code is likely to be triggered very often, this can easily cause the system to freeze. Always test your event code before deploying it.
  1. Open the configuration file called Tridion.ContentManager.config, located in the config/ subfolder of %TRIDION_HOME% (defaults to C:\Program Files (x86)\Tridion\), in a plain-text or XML editor. Find the extensions element in this file. If the element is empty (that is, if it reads <extensions/>), replace it with<extensions></extensions>. Then add a line of the following format:
<add assemblyFileName="C:\Projects\Events\MyCustomEventHandlerExample\bin\Debug\MyCustomEventHandler.dll" />
where MyCustomEventHandler.dll is the full path and name of your compiled class. If the element was empty, the fragment should now read:
<extensions>
  <add assemblyFileName="C:\Projects\Events\MyCustomEventHandlerExample\bin\Debug\MyCustomEventHandler.dll" />
</extensions>
  1. Save and close Tridion.ContentManager.config.
  2. Restart the services you stopped.