Anguilla Framework: Adding Messages With MessageCenter and $messages

The Anguilla Framework comes with a built in message center that allows you to display different types of messages and notifications to the user. You’ve probably seen these messages already – they appear at the top of the window when you do almost any action in Tridion. They can even appear as a modal, display a question that requests a user response, or display a progress message that lets the user know when a certain action is done. When building your custom GUI Extensions, instead of rolling your own status or update notification system, you can easily take advantage of the one that’s already in place (and make your extension feel like its an actual part of Tridion). Messages added with MessageCenter are even archived, so your users can go back and view them if needed (by clicking the flag like symbol in the upper left of the screen). In this post, we’ll cover how to add notifications, warnings, errors, questions, goals and progresses.

Notifications

Notifications get displayed with the “i” icon (as with the image at the top of this post). You can use these for simple updates or alerts. Notifications will disappear from the upper window after around ten seconds or so.

$messages.registerNotification(title, description, local, modal)

title – The title of the notification. This is the message that gets displayed when shown at the top of the screen.
description – (optional) A better description of the notification. Can be seen when user double clicks the message to get further details.
local – (optional) You’ve probably noticed that most of the messages get displayed across all of your open Tridion windows. Setting ‘local’ to true will only display your message at the top of the window you are working with. Note that it still goes to the MessageCenter, so you can still view it from the other windows via the Message Center icon.
modal – (optional) True or false, if true your notification will get displayed as a modal popup.

Goals


Goals are like notifications, except they are displayed with a check mark icon (and a different colored background!).

$messages.registerGoal(title, description, local, modal)

Warnings


Warnings are also similar to notifications as well and are displayed with a warning icon. Unlike Notifications and Goals, the warning message will not disappear on its own (you’ll have to click the little ‘x’).

$messages.registerWarning(title, description, local, modal)

Errors


Errors, like Warnings, do not disappear on their own, and they are displayed with an error icon. They allow for an extra area for specifics of your error.
Error message with Details.

$messages.registerError(title, description, details, local, modal)

details – Details are for displaying the details of your error. For example, this area would be a lovely place to display the stack trace of an error.

Questions

Questions allow you to supply a simple “yes/no” type of question to the user. You can add events to your message to perform an action upon confirming or canceling. Messages are great to use with the modal feature.

Question with modal option turned on

$messages.registerQuestion(title, description, local, modal, buttonLabels)

buttonLabels – (optional) Additional settings to control the labels of the button, which by default is “Yes” and “No”. { cancel: "Cancel Label", confirm: "Confirm Label" }

Question Code Samples:

var question = $messages.registerQuestion("Do you love GUI Extensions?", null, true, true, { cancel: "Hate Them!", confirm: "Love Them!" });
question.addEventListener("cancel", function (event) {
    $messages.registerNotification("Haters want to hate!");
});
question.addEventListener("confirm", function (event) {
    $messages.registerNotification("TridionLove++");
});

Progress


Progress messages let you display the progress of an action, for example, “Saving…”. Like Questions, they are a bit more interactive than just displaying a message to the user. You can set messages that will get displayed upon success of your action using setOnSuccessMessage(title, description). You can even have a cancel button appear and allow the user to cancel your action, and set a message to display upon cancellation using setOnCancelMessage(title, description). Note that the Success and Cancel messages will be displayed as Goals.

$messages.registerProgress(title, description, canCancel, local, modal)

canCancel – (Optional) True or false, when set to true will display a cancel button

Progress Code Samples:

var progress = $messages.registerProgress("Waiting...", null, true);

progress.setOnCancelMessage("You've canceled!");
progress.setOnSuccessMessage("Done waiting!!!");

progress.addEventListener("cancel", function (event) { 
    console.log("Do stuff when canceled..."); 
});

// ... somewhere later in your code, in a callback or some form of dark arts... 
progress.finish({ success: true }); // Will remove progress message and display your onSuccess message.
progress.finish(); // Will remove progress message, but not display your onSuccess message.

// You can even cancel programatically by... clicking the cancel button or calling this method directly will display the cancel message.
progress.cancel();

You can also set it to automatically call the .finish() method upon the event of another item via the .addFinishEvent(itemID, event, isSuccessEvent) method. The follow example will show a loading status, and will automatically fire our success message upon completion of our item being loaded.

var item = $tcm.getItem("tcm:1-234"),
    progress = $messages.registerProgress("Loading our item...");

progress.setOnSuccessMessage("Item Finished Loading!");
progress.addFinishEvent("tcm:1-234", "load", true);

item.load();

Playing around in a console…

If you want a quick way to experiment with MessageCenter, feel free to try the $messages api inside of the console window!

Update 08/01/2014

I’ve posted a follow up on this article on retrieving, archiving, and disposing of messages. You can find it here!

Tridion PublishEngine – Of Transactions and Publish Information

Today I thought I would give some examples of querying publish transactions (publishing queue) as well as getting publish information from specific items, like seeing which Publication Targets a page has been published to and when, or just seeing if an item has been published in general. This post is inspired by a recent question asked in the forums, but I have noticed it come up from time to time. Luckily this task is easy using the TOM.NET API and the static PublishEngine class.

IsPublished

One task you might need to attempt in your Tridion development day to day activities is to check to see if a given item has been published, or published to a particular Publication Target.  PublishEngine contains the following overloaded methods.

bool IsPublished(IdentifiableObject item)
bool IsPublished(IdentifiableObject item, PublicationTarget publicationTarget)
bool IsPublished(IdentifiableObject item, PublicationTarget publicationTarget, bool isPublishedInContext)

The first IsPublished method is useful if you just want to see if an item is published, regardless of which Publication Target it has been published to.

if (PublishEngine.IsPublished(page))
{
    // This page has been published. Do cool stuff here.
}

The second IsPublished method will return true only if the item has been published to the Publication Target passed in the 2nd argument. If the 2nd argument is null, then it’ll act just like the first method and return true if the item has been published to any Publication Target.

if (PublishEngine.IsPublished(page, pubTarget))
{
    // This page has been published to a specific publication target. Do cool stuff here.
}

The third method allows for even finer control. I haven’t personally played with this one as of yet, but the documentation for the isPublishedInContext argument states “Indicates if state should be returned regardless of the context Publication. true only check if item is published in the context Publication; otherwise, false.” I’m assuming this means that, if this argument is set to true, the method will only pass if the item is published to a particular Publication Target, and only if the item is published in it’s own context Publication.

GetPublishInfo

What if you need to get more information about an item? Like, what if you not only wanted to see what Publication Targets it was published to, but at what time too? That’s where the following method comes in hand.

foreach (PublishInfo info in PublishEngine.GetPublishInfo(page))
{
    Console.WriteLine("Published To: " + info.PublicationTarget.Title);
    Console.WriteLine("Published At: " + info.PublishedAt); // The time the page was published
    Console.WriteLine("Published By: " + info.PublishedBy.Title); // The user who published
    Console.WriteLine("Rendered With: " + info.RenderedWith.Title); // The title of the template used
}

The above will loop through each Publication Target that the item has been published to and give you some useful information about the publishing.

GetPublishTransactions

And what if you actually need to check the publishing queue to see if an item has recently been published in the past hour? The PublishEngine allows you to also query the publish transactions.

XmlElement GetListPublishTransactions(PublishTransactionsFilter filter)
IEnumerable<PublishTransaction> GetPublishTransactions(PublishTransactionsFilter filter)

Note that the above methods will throw an AccessDeniedException if the user is not a System Administrator or have PublishManagement rights in any publication. That means if your code relies on always needing to be able to check the transactions, regardless of rights, you’ll need to impersonate.

Session session = new Session("DOMAIN\username"); // Impersonate System Admin or at minimum user with PublishManagement rights.
 
PublishTransactionsFilter filter = new PublishTransactionsFilter(session);
filter.StartDate = DateTime.Now.AddHours(-1); // Add some criteria for when the publishing was started.
filter.PublishTransactionState = PublishTransactionState.Success;

IEnumerable<PublishTransaction> transactions = PublishEngine.GetPublishTransactions(filter);

foreach (PublishTransaction transaction in transactions)
{
    // Check cool stuff with the transaction, like the transaction.Items property.
}

The above will loop through all the successful transactions that has happened in the past hour. Notice the PublishTransactionState property… it allows you to only filter based on one state. But what if you need to grab anything that’s not Success or Failed perhaps, or any other combination of states? You’ll have to grab the items and filter programatically.

PublishTransactionsFilter filter = new PublishTransactionsFilter(session);
filter.StateDate = DateTime.Now.AddHours(-1);

IEnumerable<PublishTransaction> transactions = PublishEngine.GetPublishTransactions(filter)
    .Where(t => t.State != PublishTransactionState.Success && t.State != PublishTransactionState.Failed);

foreach (PublishTransaction transaction in transactions)
{
    // Do cool stuff with transactions that are not Success or Failed
}

And with that I leave. Happy developing everyone!