Crocodoc .NET API Out Of Beta

My colleague Frank Taylor and I are happy to announce that Crocodoc v1.0 for .NET is now out of Beta testing and can be downloaded from its Google Code site. Thanks to everyone who has participated in the 1.0 Beta testing and who has provided feedback or reported any issues.

And for those who may be reading this article wondering what this .NET library is for, check out my previous blog post about its beta release, Frank’s blog entry, or even the Crocodoc site itself.

Besides fixes, only one (overloaded) method has been added to this release. While the previous CrocodocDocument.Upload(string filePath) allowed you to specify a complete file path for you to upload, the method CrocodocDocument.Upload(string fileName, byte[] binary) allows you to upload a document’s byte array directly. This could be useful for when uploading files not from the file system, but say a database or content management system.

Please continue to either contact Frank or myself with any feedback, suggestions, or further issues found. And happy document embedding everyone!

Razor Mediator Version 1.3.2 Released

A new minor version of the Razor Mediator has been released and can be found at the Google Code site. For anyone who is interested in installing Razor Mediator on Tridion 2013, you will find this release especially important to you. Prior to this version, the Installer will throw an error and the installation will fail.

Besides being able to install without an error, this version also changes how the configuration is done slightly. Prior to 1.3.2, the template ID for Razor Mediator was generated during installation by selecting the highest free available ID. With an out of the box Tridion setup, this would normally have resulted in a template type of “8″. Tridion 2013 comes with a new XSLT Mediator, but they have left the ID’s of 8 and 9 empty. So, installation for 1.3.2 will attempt to use 8 if its available, otherwise it’ll pick the ID just like it use to do.

An important thing to note is that you may have to manually modify this ID if you are porting from another system that used a different ID for the Mediator. If the ID’s don’t match up, you will get an error during the content porter process.

Thanks to Nicholas Vander Ende, Frank Taylor, and Piti Itharat for reporting and troubleshooting the installation error in 2013. A special thanks to Nicholas for actually finding the fix to the problem as well.

ComponentPresentations and ComponentTemplateModel

Thanks to Chris Curry for spotting that ComponentPresentationModel’s Template property was not returning a ComponentTemplateModel type, but rather just the Tridion’s ComponentTemplate type. This means you would have to grab the ItemFields in order to fetch fields. This version fixes the CompoenntPresentationModel’s Template property.

@foreach (var cp in ComponentPresentations) {
    <div>cp.Template.Fields.FieldName</div>
}

Get Version From Template

Although you can get the Razor Mediator version by looking at the Tridion.ContentManager.config file, sometimes you may not have access to the server and need another quick way to get the version. 1.3.2 comes with a “Version” property in the base template that you can output to check the version.

    <div>Version: @Version</div>

Models.GetComponentTemplate

The ModelUtilities class now comes with a GetComponentTemplate method to easily pull out ComponentTemplateModels.

@{
    var ct = Models.GetComponentTemplate("tcm:1-2345-32");
}

Thanks again to everyone for your feedback and suggestions!

Razor Mediator Version 1.3.1 Released

The next version of the Razor Mediator, version 1.3.1, is now up and ready to be downloaded at its Google Code site, and its updated documentation can be found here. This update includes mainly fixes for issues reported, though it does include a couple of new (or features that were missing) features as well. If after upgrading to version 1.3 and you have been receiving errors while attempting to do imports from the configuration, this may be the release for you!

Fixes for Imports

As mentioned, version 1.3 caused some issues when trying to use the new Where Used functionality along with global imports from the configuration. Errors included messages similar to “tcm:0-234-2048 does not exist”.

Fixes to Documentation

Thanks to Robert Curlette for supplying documentation that removed the smart quotes from the code samples in the documentation. The new version of the documentation and forward will be based off of his ascii documentation.

Non-Cache DynamicPackage

Thanks to Dominic Cronin for supplying a patch for the DynamicPackage to make it not cache the package’s values. This will ensure you don’t run into issues if the context of those package items gets changed during the razor’s scope.

Indexes for DynamicItemFields and DynamicPackage

You can now access fields for ItemFields and for the Package using indexers. This can help when creating generic templates, or when working with package items that contain dots in the item names.

@Fields["FieldName"]
@Package["SomeName"]
@Package["Some.Name.With.Dots"]

GetFields and GetFieldNames

Also to assist with the creation of making generic templates, DynamicItemFields now has a GetFields() and a GetFieldNames() method. GetFieldNames() returns an array of strings containing the field names, while GetFields() returns the underlying Dictionary<string, object> that represents the ItemFields.

@foreach (string name in @Fields.GetFieldNames()) {
    <span><strong>@name</strong>: @Fields[name]</span>
}

// var field is of type KeyValuePair<string, object>
@foreach (var field in @Fields.GetFields()) {
    <span><strong>@field.Key</strong>: @field.Value</span>
}

Fix to IsSiteEditEnabled

The IsSiteEditEnabled property would throw an error when working with a Publication Target that never had its Site Edit enabled or disabled yet. This is now fixed.

ParentKeywords and RelatedKeywords

These properties have been added to the KeywordModel, and both return a List of KeywordModel’s.

@foreach (var kw in @Fields.SomeKeyword.ParentKeywords) {
    <span>@kw.Title</span>
}

Thanks again to everyone who has been posting suggestions, issues, and fixes. Special thanks to Robert Curlette who has been the guinea pig for most of these updates!

Razor Mediator Version 1.3 Released

Its taken much longer than I had originally anticipated, but the next version of the Razor Mediator has just been submitted to the SDL team. As usual, you can find the installer for this package here and the updated documentation for this version here. So what exactly is new in this package?

Working Where Used Functionality

Have a lot of Razor Imports and sad because its hard to track down where exactly they are used? Or have the blues from Content Porting since you have to make sure you CP your import files first before the rest of your Razor Templates? The great news is that with Version 1.3, including razor imports either through importRazor(“path”) statements or via the razor.mediator configuration setting will now finally be set as a reference so that these imports show up as Where Used! Just in case for some odd reason you absolutely do not like this features, there is also a new element in the config called “importSettings”, which allows you to turn on/off this feature. You can even turn on/off imports from importRazor statements and imports from the configuration separately.

<importSettings includeConfigWhereUsed="true" includeImportWhereUsed="true" replaceRelativePaths="false" />

The Where Used won’t kick in automatically once you upgrade to this version… you’ll have to Save your Razor Templates for the references to take place.

Relative WebDav URLs Supported!

Thanks’s to Will Price for suggesting this one! Import statements in version 1.2 only accepted TcmUri’s and full lengthy WebDav URL’s. As of Version 1.3, you can now supply relative WebDav URL paths! These paths to the imports are relative to the Razor Template that’s calling them.

@importRazor("Same Level Helper Functions.cshtml")
@importRazor("./Also Same Level Helper Functions.cshtml")
@importRazor("My Helper Functions/Global Helper Functions.cshtml")
@importRazor("My Helper Functions/Nav Functions/Main Navigation Functions.cshtml")
@importRazor("../Previous Level Functions.cshtml")
@importRazor("../../Even More Previous Level Functions.cshtml")

You probably noticed that “replaceRelativePaths” attribute in the previous importSettings config example? When set to “false” (out of the box setting), your relative import paths will stay relative. But if for some reason you would like these to automatically be transformed into the full WebDav URL, set this to true and upon saving your templates, the paths will be turned into the full paths.

Site Edit Enabled!

Razor Mediator 1.3 now includes a property named “IsSiteEditEnabled”. As the name may suggest, this property will check the Publication Target you are publishing to to see whether or not SiteEdit (inline editing) is enabled. This is useful for when you want to render specific HTML (like regions!) only for your editable staging site. This only works for Tridion UI 2012, and not previous versions of SiteEdit.

@if (IsSiteEditEnabled) {
    <strong>This page is SiteEdit Enabled!</strong>
}

Also added by default to version 1.3 is an enhancement request that came in for the RenderComponentField methods. Prior to Version 1.3, these methods would throw an error if the field was empty. Now these methods will spit out an empty tcdl tag. You can also have it spit out an empty string by using the new last argument to this field. The following is assuming that “Fields.FieldName” is empty.

@RenderComponentField("Fields.FieldName", 0)
@RenderComponentField("Fields.FieldName", 0, false)

In the first example, an empty tcdl tag like <tcdl:ComponentField name=”Fields.FieldName” index=”0″></tcdl:ComponentField> will get output so that you still have a section on your staging page for adding text to this area. The second example will just output an empty string and no tcdl tag.

Template Models

Version 1.3 now includes Template Models for the quick and easy access to template metadata that you have grown use to! @ComponentTemplate (accessible only from Component Templates), @PageTemplate and @Page.PageTemplate (accessible only when there’s a page that’s accessible), and @RazorTemplate (the Razor Template Building Block itself).

@if (IsComponentTemplate) {
    <span>@ComponentTemplate.Metadata.FieldName</span>
}

@if (Page != null) {
    <text>The following can be accessed from both Page Templates and Component Templates (only when a Page object is available though)</text>
    <span>@PageTemplate.Metadata.FieldName or @Page.PageTemplate.Metadata.FieldName</span>
}

@if (IsPageTemplate) {
    <text>While this example will only work when its a Page Template.</text>
    <span>@PageTemplate.Metadata.FieldName or @Page.PageTemplate.Metadata.FieldName</span>
}

<span>@RazorTemplate.Metadata.FieldName</span>

Other Changes and Fixes

For a full list of updates and fixes that were made in this version, please check out the Change Log.

Thanks To You

And I just wanted to personally thank everyone who has supported this project through kind comments, reporting issues, bugs and suggestions, and for testing the many features. This project definitely would not have come this far without you guys. :)