GUI Extensions create a seamless experience for Tridion editors, providing shortcuts, new possibilities for bulk-editing and blueprint-aware tools that ease the task of daily content maintenance and improves the efficiency of all operations. In this article I quickly create a new GUI Extension using the WhoDidIt example as the basis. I also show how to convert an existing custom page, BCopy, to a new GUI Extension using the Core Service. I hope after reading this you will be able to also convert your custom pages to GUI Extensions with little effort.
Getting Started
I use the previous GUI Extension tutorial, WhoDidIt?, as a basis for creating this new GUI Extension. There will be lots of find/replace action going on – so if this is your first time creating a GUI Extension then I strongly recommend you work your way through my previous article before continuing here. The first article explains the overall concepts and the relationships between pieces. Here I will focus on getting a GUI Extension created as soon as possible – re-using as many pieces from the GUI Extension WhoDidIt. In the first part I will walk through how to create the GUI Extension client using the previous solution of WhoDidIt as the basis on our BlueCopy extension. The second part focuses on the “Core” work – migrating the Tridion TOM API code to use the new Core Service.
What are BlueTools?
BlueTools are my Tridion Blueprint-focused tools to help you work with Tridion Blueprinted content. This first extension in the BlueTools suite is ‘BlueCopy’, a modern interpretation on the BCopy custom ASP page. BCopy and this extension will do 1 thing and try to do it well – copy an item with its’ Blueprint children.
Downloads
WhoDidIt? GUI Extension Files– Start
BlueCopy GUI Extension Files – Solution- We create this below
Overview
Step 1: GUI Extension Client-Setup – Show a popup (~30 minutes)
Step 2: GUI Extension Server Setup – Create the Web Service locally and call the Tridion Core Service (~15 mins)
Step 3: Adding a new Web Service – Adding our new Service to ServiceStack (~15 mins)
Step 4: Deploy the GUI Extension Web Service to our CMS (~20 mins)
Step 5: Wire the GUI Extension client to the Web Service on the Server
Step 6: Converting ASP TOM API code to Tridion 2011 Core Service code
Step 7: Finishing up – polishing the GUI and adding another field
Step 1: GUI Extension Client-Setup – Show a popup (~30 minutes)
1. Get the GUI Extension WhoDidIt files from GitHub, https://github.com/rcurlette/WhoDidIt/downloads. Extract it and rename the files from WhoDidIt to our extension name. Rename the folder from ‘rcurlette-WhoDidIt-552c9a2’ to ‘BlueTools’ or your GUI Extension.
2. Rename the files
- WhoDidItCmd.js ->GuiExtensions\BlueTools\GuiExtension\client\js\BlueToolsCmd.js
- WhoDidIt.css -> GuiExtensions\BlueTools\GuiExtension\client\css\BlueTools.css
- WhoDidIt.config -> GuiExtensions\BlueTools.config
3. Update files. Find / replace WhoDidIt and Sherlock with your tool name.
- BlueTools.config -> Find / replace ‘Sherlock’ with BlueTools and ‘WhoDidIt’ with BlueCopy. Replace the text ‘Who Did It?’ with what text you want shown on the right-click, for example, ‘BlueCopy’.
- Open the GUI Extension BlueToolsCmd.js file. Find / Replace Sherlock with BlueTools and WhoDidIt with BlueCopy. Save.
4. Update the GUI Extension action – Open the BlueToolsCmd.js file, change the _execute method alert message to ‘alert(‘Really Excellent!’);’ and comment out all lines starting with ‘var selectedID’ until popup.open();. This update will show only the popup and comment out all other lines, not worrying about other client HTML / JS files.
5. Update BlueTools.config file and add an assignid value. Whenever you change the config file the GUI flushes the cache automagically. Nice! 🙂
old:
<ext:extension name="BlueToolsExtension" assignid="" insertbefore="cm_refresh">
new:
<ext:extension name="BlueToolsExtension" assignid="BlueCopy" insertbefore="cm_refresh">
6. Deploy to Server – On the CMS server, create a new folder under ‘C:\Program Files (x86)\Tridion\web\WebUI\Editors’ for the new GUI Extension. I create a folder called BlueTools. Copy all the files in the GuiExtensions\BlueTools\GuiExtension folder to the server at ‘C:\Program Files (x86)\Tridion\web\WebUI\Editors\BlueTools’. Then you should have BlueTools\GuiExtension.
7. Create IIS Virtual Dir – Open IIS on CMS Server, Go To Web Sites, SDL Tridion 2011, WebUI, Editors. Right-click, select create a new IIS Virtual Directory to host the GUI Extension, name it BlueTools, and browse to the folder you copied the BlueTools GUI Extension to on the server.
8. Edit the System.Config located at ‘c:\Program Files (x86)\Tridion\web\WebUI\WebRoot\Configuration\System.Config‘, and let Tridion know about our new extension.
<editor name="BlueCopy">
<installpath>C:\Program Files (x86)\Tridion\web\WebUI\Editors\BlueTools\GuiExtension\</installpath>
<configuration><strong>BlueTools</strong>.config</configuration>
<vdir>BlueTools</vdir>
</editor>
9. Flush browser cache. (Ctrl-shift-delete in Chrome) Refresh the GUI, see our new option in the right-click context menu. Since WhoDidIt did not include a ribbon extension you will not have a ribbon button here.
10. Test the GUI Extension client using the right-click menu option ‘BlueCopy’. You should see an alert with the text ‘Really Excellent!’
*Note: On my first test I saw the text in the menu but clicking on it did not do anything! Opening up the Javascript console in Chrome (F12 key) and in the Console window I see this message: “Command ‘BlueToolsCommand’ is not registered“. To fix this I needed to add an ID to the <ext:extension line. Maybe this is because I have more than 1 GUI Extension registered and also inserting at the same position? For more info about all the values in the config file have a look at my previous post, http://www.curlette.com/?p=279.
old:
<ext:extension name="BlueToolsExtension" assignid="" insertbefore="cm_refresh">
new:
<ext:extension name="BlueToolsExtension" assignid="BlueTools" insertbefore="cm_refresh">
Review:
We did it! We have successfully added another GUI Extension Client. It doesn’t do much yet – no Tridion API magic. Now time to create the server-side web service to do something with the Tridion API and call our popup from the _execute method. If you have any problems – review the config file and my debug article.
Step 2: GUI Extension Server Setup – Create the Web Service locally and call the Tridion Core Service (~15 mins)
1. Get the Tridion2011ServiceStack project from GitHub
2. Add your CMS Url. Open the solution in Visual Studio 2010 SP1. Do a find / replace for TridionDev2011 with your CMS server name for all files in Solution. Change the look-in option to ‘Entire solution. You should have 53 replacements. Save all.
3. Update the web.config file and put in your CMS server URL, Username, and password
4. Add the Tridion Core Service DLL reference to the solution. Get it from your Tridion server in the /bin/client folder. Copy it locally before adding it – don’t add it from a network share. It is not included in the ServiceStack project because it is a Tridion file.
5. Step through code. Build. Hit F5 (play) to Debug solution – the test page for WhoDidIt appears. Note the url and port # visual studio uses in your browser. If your URL is not ‘http://localhost:61860’ then copy it and update the page ‘GetTridionItem.htm’, replacing the URL with your localhost URL. Otherwise, hit the ‘Go’ button and you should hit the breakpoint ‘ return Repository.GetByUri(request.Uri);’ in the OnGet method of our ‘TridionItemRepository’.
Review
Developing locally is great – we can write our Tridion API code in the Service, develop and debug our Core Service Tridion API calls directly in our Visual Studio development environment. Our test page calls the Tridion2011ServiceStack Web Service via AJAX and we hit our Service method calling the Tridion API and can step through the code. So far, so good.
Step 3: Adding a new Web Service – Adding our new Service to ServiceStack (~15 mins)
1. Create a new model class. Right-click on the models folder, select ‘Add new class’. Add any properties to the class you want to return to the js client. You can also copy/paste the properties from the TridionItem class. I am creating a ‘BlueCopyItem’ model and adding 3 properties I know I’ll need – Title, URI, and Error (to hold the error message to pass back to the js client).
namespace Tridion2011ServiceStack.Models
{
public class BlueCopyItem
{
public string Title { get; set; }
public string Uri { get; set; }
public string Error { get; set; }
}
}
2. Create a new Service class. This handles the request from the GUI Extension client. Right-click on the Services folder, select ‘Add new class’. I called mine ‘TridionBlueCopyService.cs’. Copy / paste the code from TridionItemService. Replace ‘TridionItem’ with the name of your model class from step 1, ‘BlueCopyItem’. Don’t forget to change the ‘Look in’ option to ‘Current document’ and not ‘Entire Solution’. You should have 4 replacements. Also, select the match case – otherwise it will rename both your Class name (TridionItem) and the variable names (tridionItem).
Remember to inherit from the RestServiceBase class.
: RestServiceBase<BlueCopyItem>
3. Create a new Repository class. Right-click on the Repositories folder, select ‘Add new class’. I called mine ‘BlueCopyRepository’. Copy / Paste code from TridionItemRepository. Update the code – rename ‘TridionItemRepository’ with ‘YourModelClassRepository’. Replace ‘TridionItem’ with ‘BlueCopyItem’ and ‘tridionItem’ with ‘blueCopyItem’. Remove the line 24 adding the LastModifiedProperty since we do not have it in our model. // remove -> tridionBlueCopy.LastModifiedBy = versionInfo.Revisor.Title;
4. Add our service mapping – Open AppHost.cs and add 1 more line below ‘.Add<TridionItem>(“/tridionItem”)’, where TridionItem is your model class name and /tridionItem is the URL you want to use for your web service. This can be whatever you want. I added this:
.Add<BlueCopyItem>("/blueCopy");
5. Register our repository – In AppHost.cs register your new Repository. Add a new line below ‘container.Register(new TridionItemRepository());’ on line 62 and change TridionItemRepository with your repository name.
container.Register(new BlueCopyRepository());
6. Build, add namespaces as needed.
7. All done! No config needed. 🙂 Service Stack is built using the convention over configuration principle and steps 4 and 5 are all we need to do to make our new service visible to Service Stack.
8. Make a new test page. Copy / paste GetTridionItem.htm and give it a new name such as ‘BlueCopyTest.htm’
9. Put the new Web Service URL in the test htm page from the AppHost.cs file (ie’ /tridionBlueCopy). Replace ‘http://localhost:61860/api/tridionItem’ with ‘http://localhost:61860/api/yourServiceUrl’ located in the test htm file. Mine is: ‘url: “http://localhost:61860/api/blueCopy”,’
10. Set the new test page as your default start page by right-clicking on it and choose ‘Set as Start Page’.
11. Add a breakpoint to the new Repository class (ie. BlueCopyRespository.cs), line ‘CoreServiceClient client = new CoreServiceClient();’ (assuming you did not change anything in the Repository code yet).
12. Hit play, run in debug mode. Your new htm test page should show up. Push the ‘Go’ button and your new breakpoint should be hit. Step through the Repository OnGet code, and at the end your page will show the Title and URI of the item. Congratulations – you are now ready to add your new code.
Note: If you get a popup and the text looks like jquery2189072189723131 then you’ve got an error in the Repository Tridion code. 🙂 Time to debug the server. I decided to place another breakpoint on the OnGet method in the BlueCopyService class. This is called first. I got into the debugger this time, but when pressing F11 to step into the repostitory I got a popup from Visual Studio saying it could not find my repository. I forgot to add it to the AppHost Repositories Funq container! To sovle this I opened the AppHost.cs file, and added
container.Register(new TridionBlueCopyRepository());
Review
It’s fun to add a new web service so easily and then step through the code in Visual Studio with the debugger. Creating a web service and configuring it for test is not an easy step – there are several files involved and many places we find/replace the original class names with our new model class. No worries – once this is done you will not need to do it again for this web service. Also, I find it fairly straight-forward and if you follow the steps above you should have your new web service ready to go in no time. One advantage to this approach is you can call your new web service from any client, an HTML test page as shown above, your new GUI Extension, or a classic ASP custom page!
Step 4: Deploy the GUI Extension Web Service to our CMS (~20 mins)
1. Copy Tridion2011ServiceStack files to server, usually I create a new folder under InetPub\wwwroot. I called mine ‘BlueToolsWebService’. I deploy my MVC website using the ‘Publish’ option of Visual Studio. I have a drive mapped to my server and then choose ‘File System’ in the publish method listbox. Then, in IIS, create a website to host the ServiceStack MVC Web Service (or host the Web Service as a Windows Service or Console App). Don’t forget to change the App Pool to a .NET 4.0 App Pool or it will not run. You may also want to run it on a different port. In my previous post I describe this in more detail.
2. Test the Web Service. Open a web browser and go to the URL of your web service. You should see a reply from ServiceStack like this one: “Snapshot of BlueCopyItem generated by ServiceStack”. This works! Open the popup.js file on our local dev box and chage the URL to the website URL from the browser.
3. Debug the results in Chrome. Now hit F5 and run the test page again in Visual Studio. Use the Developer Tools (F12 key) and go to the Scripts tab. Select the BlueCopyTest.htm file in the dropdown and set a breakpoint on the line with ‘ $(“#feedback”).html(“<div class=’successMessage’>Title’. Now, hit ‘Go’ and our breakpoint will be hit. then mouseover the data object in the line with ‘success: function (data) {‘ and see the title and uri properties. You can also highlight ‘data’, right-click, and select ‘Add Watch’ to see the values.
Step 5: Wire the GUI Extension client to the Web Service on the Server
1. Enable the popup. Open the GUI Extension .js file with the _execute method. Mine is called ‘BlueToolsCmd.js’. The location on the server might be something like: C:\Program Files (x86)\Tridion\web\WebUI\Editors\BlueTools\client\js\BlueToolsCmd.js UnComment the lines starting with ‘selectedId’ and ending with ‘popup.open’
2. Add text to popup.htm. The original WhoDidIt popup only had an AJAX call and does not display anything. Let’s add ‘Hello World’ text to the popup.htm so we have something to see when we call it.
3. Confirm the url to the popup is working. Popup on server might be located at ‘WebUI\Editors\BlueTools\client\html’. Test this in the browser. If your CMS URL is http://TridionDev2011 then the test URL would be http://TridionDev2011/WebUI/Editors/BlueTools/client/html/popup.htm.
4. Test in CMS. Now let’s clear our browser cache and try our GUI Extension again. If you see the popup- congrats! If not, double-check your .js file _execute command, make sure it is deployed, and refresh your browser. Also, open up the Chrome debugger or FireBug and see my post about debugging.
3. Add web service URL to popup.js. Our client is now 100% working and also showing the popup. Let’s call our new Web Service. Change the URL property in the popup.js file located in the C:\Program Files (x86)\Tridion\web\WebUI\Editors\BlueTools\client\html\js folder to point to our new web service and try again. This assumes you have not changed any code in the repository class.
You will see the URL as url: “‘http://TridionDev2011:8001/Tridion2011ServiceStack/api/tridionItem”. Change TridionDev2011 to your CMS URL and ‘tridionItem’ to your new Web Service URL (should look like your test htm page). My new url is ‘http://TridionDev2011:8001/BlueToolsWebService/api/blueCopy’ Note: Clear browser cache again and refresh.
4. Test in GUI, Debug the data returned in Chrome.
– Run GUI Extension
– When popup is open, load the Chrome Developer Tools (F12), scripts window, select popup.js.
– Put breakpoint on line $(“#suspect”).text(data.lastModifiedBy);
– Reload popup html window, breakpoint is hit.
– Minimize call stack window on right, open Scope variables
– Open Closure, data and see your properties here. This is your model object returned from ServiceStack. Notice your propery names are camelCased.
Review
This is the most critical part – where we see our 2 major pieces talking to each other. Give yourself a pat on the back – you’ve made it through the most difficult part. Now we’re ready to move onto the real work – using the Tridion API to do something. Right now all the pieces are in place, working, and we’re finally ready! The 5 pieces are: Extension Config -> .js (with _execute) -> popup.htm -> popup.js -> Web Service -> Tridion Core Service
Step 6: Converting ASP TOM API code to Tridion 2011 Core Service code
Tridion introduced the Core Service in Tridion 2011 and announced this is the official way to talk with the Tridion API outside of the Event System or Templates. We will use the Core Service to talk to the API and do the work. Our AJAX call is passing the Component URI to the Web Service.
I do this all locally and use a local htm test page with the javascript / css locally as well. Just as we did in Step 2 above – we will set a breakpoint in our Repository class and step through the Tridion Core Service Code.
In this example I need to port my existing classic ASP Custom Page code for copying an item and BluePrint children to the new Core Service. Below are some highlights and points about the differences.
The Core Service code has 3 main parts:
1. Create a new copy of the Parent source item (Page or Component)
2. Get Localized Versions of the source item
3. For each Localized Version, localize the new copy and update the contents with the localized source item.
1. Copy the Parent Tridion Object
TOM API:
Function CreateNewItemCopy(organizationalItemUri, itemType, title, xml, directory, filename)
'response.write "create new item" & organizationalItemUri & "," & itemType & "," & title & "," & xml & "," & directory & "," & filename
Dim newItem : set newItem = tdse.GetNewObject(itemType, organizationalItemUri)
newItem.UpdateXml(xml)
newItem.Title = title
if(itemType = 64) then ' page
newItem.FileName = filename
elseif(itemType = 4) then ' sg
newItem.Directory = directory
end if
newItem.save(true)
CreateNewItemCopy = newItem.id
set newItem = nothing
End Function
Core Service API: *Note: I did change the fundamental approach here since I now use the copy method
private string CreateNewItemCopy(string title, RepositoryLocalObjectData source, string filename)
{
string newItemUri = "";
try
{
ItemType tridionItemType = GetTridionItemType(source);
string orgItemUri = source.LocationInfo.OrganizationalItem.IdRef;
var newItem = client.Copy(source.Id, orgItemUri, true, new ReadOptions());
newItem.Title = title;
if (tridionItemType == ItemType.Page)
{
PageData pageData = newItem as PageData;
pageData.FileName = filename;
client.Update(pageData, new ReadOptions());
}
else
{
client.Update(newItem, new ReadOptions());
}
newItemUri = newItem.Id;
}
catch (Exception ex)
{
throw;
}
return newItemUri;
}
Highlights / Differences:
The Tridion TOM provides us a nice easy way to create content in any type of item – UpdateXml. The Tridion Core Service does not have this method but instead uses an Update method on the Web Service client. I posted a question on StackOverflow about this and got a great response – not only was my answer provided, but a new suggestion of using the Copy method of the API instead of UpdateXML. 🙂
Copy item – also passing in Read options to make sure I can read data later.
' VBScript / TOM
Dim newItem : set newItem = tdse.GetNewObject(itemType, organizationalItemUri)
newItem.UpdateXml(xml)
// Tridion CORE Service / .NET
var newItem = client.Copy(source.Id, orgItemUri, true, new ReadOptions());
2. Get Localized Versions
I really like the new approach with BluePrintChainFilterData instead of GetListUsingItems (from TOM) to get the localized child elements. The Core Service and the filter BluePrintChainFilterData also returns the Parent item – so watch out – you may need to filter it out as I do here. Big thanks to user978511 on StackOverflow for the help and example code http://stackoverflow.com/questions/9515647/getlistusingitems-with-tridion-core-service-returns-more-items-than-tom.
TOM API:
Function GetLocalizedItemNodes(itemUri)
Dim tridionItem : set tridionItem = tdse.GetObject(itemUri,1)
Dim rowFilter : set rowFilter = tdse.CreateListRowFilter()
call rowFilter.SetCondition("ItemType", GetItemType(itemUri))
call rowFilter.SetCondition("InclLocalCopies", true)
Dim usingItemsXml : usingItemsXml = tridionItem.Info.GetListUsingItems(1919, rowFilter)
Dim domDoc : set domDoc = GetNewDOMDocument()
domDoc.LoadXml(usingItemsXml)
Dim nodeList : set nodeList = domDoc.SelectNodes("/tcm:ListUsingItems/tcm:Item[@CommentToken='LocalCopy']")
set tridionItem = nothing
set domDoc = nothing
set GetLocalizedItemNodes = nodeList
End Function
Core Service API:
private XContainer GetLocalizedItems(string itemUri)
{
XContainer localizedItems = null;
try
{
BluePrintChainFilterData filter = new BluePrintChainFilterData();
filter.Direction = BluePrintChainDirection.Down;
localizedItems = client.GetListXml(itemUri, filter);
}
catch (Exception ex)
{
throw;
}
return localizedItems;
}
3. Update Localized Items
Some lines in the code commented out with //… – there is code there – please see the source code on GitHub.
TOM API:
Sub UpdateLocalizedItem(itemXml, itemUri, pubUri, filename, directory)
Dim newTridionCopy : set newTridionCopy = tdse.getObject(itemUri,1, pubUri)
//...
if(newTridionCopy.Info.IsLocalized = false) then
newTridionCopy.Localize
end if
//...code removed...
newTridionCopy.UpdateXml(itemXml)
newTridionCopy.Title = newParentTitle
' set sg and page props
if(itemType = 64) then ' page
newTridionCopy.FileName = filename
elseif(itemType = 4) then ' sg
newTridionCopy.Directory = directory
end if
newTridionCopy.Save(true)
// ...
End Sub
Core Service API:
private string UpdateLocalizedItem(string title, string uriLocalizedSource, string newItemUri)
{
try
{
ItemType tridionItemType = GetTridionItemType(uriLocalizedSource);
var newItem = client.Read(newItemUri, new ReadOptions()) as RepositoryLocalObjectData;
var oldItem = client.Read(uriLocalizedSource, new ReadOptions());
if (newItem.MetadataSchema != null)
{
var newItemMetadataSchema = client.Read(newItem.MetadataSchema.IdRef, new ReadOptions()) as SchemaData;
newItem.Metadata = GetMetadata(newItem.Metadata, newItemMetadataSchema.NamespaceUri);
}
if (tridionItemType == ItemType.Page)
{
PageData newPage = newItem as PageData;
PageData oldPage = oldItem as PageData;
newPage.ComponentPresentations = oldPage.ComponentPresentations;
newPage.Title = title;
client.Update(newPage, new ReadOptions());
return newPage.Id;
}
else if (tridionItemType == ItemType.Component)
{
ComponentData newComp = newItem as ComponentData;
ComponentData oldComp = oldItem as ComponentData;
newComp.Schema = oldComp.Schema;
newComp.MetadataSchema = oldComp.MetadataSchema;
newComp.Content = oldComp.Content;
newComp.Metadata = oldComp.Metadata;
newComp.Title = title;
return newComp.Id;
}
}
catch (Exception ex)
{
log.Error(ex.Source + "," + ex.Message + "," + ex.ToString());
log.Error(ex);
}
return uriLocalizedSource;
}
Review: Creating the Core Service code is where we get to talk with the Tridion API and some familiar old school objects and names come back into the light. I usually do all my Core Service development locally, including debug, and only use the Server log files to know that something went wrong. No more fighting with other developers over remote Windows Server sessions! 🙂 I cannot express enough how nice this is – and how it speeds up the development / debug / deploy cycle. While there is a lot more to know about the Core Service to build good solutions – the community and documentation examples provided the help I needed. Please grab the source code from GitHub for all the details.
Step 7: Finishing up – polishing the GUI and adding another field
GUI Extensions are by nature a client-side HTML / JavaScript / jQuery application making Web Service calls. The better your client side dev skills are – the better your GUI Extension will feel. Unfortunately, most Tridion developers have spent little time doing client development (me included!) and this is a time consuming part of writing a GUI Extension. We can no longer avoid JavaScript!
Adding new properties – SourceTitle and Filename
Currently we only return the title of the new copied item- but what if we wanted to also return the title of the original item? No problem.
1. Add the property to the Model
public class TridionCopyItem
{
public string Title { get; set; }
public string SourceTitle { get; set; }
public string Filename { get; set; }
2. Set the property value
// Create the Response Object to send back via Ajax to our GUI Client
TridionCopyItem tridionItem = new TridionCopyItem()
{
Title = GetCmsEditUrl(newItemUri, title),
Uri = newItemUri,
SourceTitle = itemToCopy.Attribute("Title").Value,
Filename = filename
};
3. Read the value in the js client
success: function (data) {
$(document).ready(function () {
/* Render the template with the movies data */
$.each(data, function () {
$('<div>' + this.sourceTitle + '<span class="icon-arrow-right" style="padding-right:4px;padding-left:4px;"></span>' + this.title + '</div>').appendTo("#componentList");
});
Adding input fields to HTML form for the Title
Adding another input field is no problem. We simply add it to our HTML form and it automatically gets serialized by jQuery into JSON and sent via AJAX to our ServiceStack Web Service. In the Web Service our Model should have a Property with the same name, and our Service class needs an input parameter with the same name.
Look and feel
I use the Twitter Bootstrap CSS framework for all custom pages and GUI Extensions. This time I also decided to adopt the Golden Ratio for the popup size. Overall I am very happy with the design and the look.
I added more jQuery and HTML to the final form but did not change the Web Service. Maybe this is typical for a GUI Extension to first get the Core Service working and then spend lots of time polishing the jQuery and HTML interaction with the user. Consider the skillset for your extensions – find your local JavaScript / jQuery expert and get them involved in the GUI Extension project.
Summary:
Building GUI Extensions involves 3 main activities. First, get the menu option in the GUI and a popup saying ‘Hello’. Second, setup the Web Service. Third, get the Core Service doing the magic bits with the Tridion API. The first step, with the GUI, involves a lot of server-side work of updating config files, deploying js files, and working with IIS. However, the Tridion API work with the Core Service feels completely different – doing the work in the Visual Studio development tool and being able to iterate quickly. Overall I like the separation of concerns – it just needs to become clear in our minds what happens where and we can easily design nice GUI Extensions without too much work.
I hope you managed to follow along and feel more comfortable about creating GUI Extensions. Now time to start coding the next one… 🙂
WhoDidIt? GUI Extension Files– Start
BlueCopy GUI Extension Files – Solution