4

Is there a way to publish binaries in the package that are not Tridion assets? I have a Page Template that creates JSON files and places them into the package of a rendering page.

enter image description here

I would like to have those files created from the Page Template published out into a Tridion Structure Group. However the AddBinary method requires a Component. How can I publish these binaries without splitting them up into separate page outputs.

Our site is fully static. No dynamic content delivery.

Am I missing something? Thanks in advance.

  • Thanks guys! I have added some dummy components to the page and will start testing this set up. Thanks also to David for getting me started on the publishing code. – Trevor Bartlett Sep 6 '13 at 13:46
  • 1
    UPDATE: The code looks to be working great. As was cautioned...if there is no component link in the AddBinary, the files will be orphaned. I have three dummy components for the linked item that are added to the page. Thanks for all your help on this! – Trevor Bartlett Sep 6 '13 at 17:01
6

As you noticed, you can add binaries on the fly with AddBinary, however they always need to be variants of a component (although not necessarily a multimedia component). The reason for this relationship is to ensure that the ad hoc binaries are managed ie, they can also be unpublished (when the related component is unpublished).

The simplest way to manage this is to have the JSON created in your Component Template, and use the context component as the related component. Most of the implementations I have worked on that require adhoc binaries (for example a pdf version of the article being published, or some XML data used to provide content resources for a flash movie) - this has made sense. Its difficult from your description to see if this could also make sense for you.

If the binary generation really can only belong in the Page Template then you could consider using dummy component(s) as your related component, however think carefully about the circumstances in which you would want the JSON files to be removed from the webserver and how you would go about this.

| improve this answer | |
4

You could publish them as a binary variant using one of the AddBinary() methods of the RenderedItem class.

I just knocked a couple of test TBBs: One to create a test JSON file in the package with filename and extension attributes, the other to retrieve such items and publish them out. They work great in Content Manager Preview but I've done limited testing, so use with caution and test well...

I'm not setting a related component for the binary variant (I'm specifying null for the relatedComponent parameter in the AddBinary methods) but depending on your use case you might want to - Setting null as the relatedComponent means that your binary can never be cleaned up by the deployer (e.g. by unpublishing your component/page).

See https://gist.github.com/DavidForster/6455674 for the full set, but here's the main TBB

using System;
using Tridion.ContentManager;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Templating.Assembly;

namespace Test.JsonTemplates
{
    [TcmTemplateTitle("Publish JSON package items as Variants")]
    public class PublishJsonFiles : ITemplate
    {
        public void Transform(Engine engine, Package package)
        {
            //Get all items of unknown type from the package
            var items = package.GetAllByType(ContentType.Unknown);

            //Remove all items that are NOT JSON files
            foreach (var item in items)
            {
                if (!item.Properties[Item.ItemPropertyFileNameExtension].Equals("json", StringComparison.OrdinalIgnoreCase))
                {
                    items.Remove(item);
                }
            }

            //Check the package values for an optional structure group ID to publish to
            var optionalStructureGroupId = package.GetValue("jsonStructureGroup");
            StructureGroup jsonStructureGroup = null;

            //Go get the structure group from Tridion if an Id has been specified
            if (!String.IsNullOrWhiteSpace(optionalStructureGroupId))
            {
                var structureGroupTcmUri = new TcmUri(
                    Convert.ToInt32(optionalStructureGroupId),
                    ItemType.StructureGroup,
                    engine.PublishingContext.RenderedItem.ResolvedItem.Item.Id.PublicationId);
                jsonStructureGroup = (StructureGroup)engine.GetObject(structureGroupTcmUri);
            }

            //Publish out the JSON files
            foreach (var item in items)
            {
                var filename = item.Properties[Item.ItemPropertyFileName] + "." + item.Properties[Item.ItemPropertyFileNameExtension];

                //If no structure group has been specified, publish to the default images directory configured for the publication
                if (jsonStructureGroup == null)
                {
                    engine.PublishingContext.RenderedItem.AddBinary(
                        item.GetAsStream(),
                        filename,
                        filename,
                        null,
                        "application/json");
                }
                else
                {
                    engine.PublishingContext.RenderedItem.AddBinary(
                        item.GetAsStream(),
                        filename,
                        jsonStructureGroup,
                        filename,
                        null,
                        "application/json");
                }
            }
        }
    }
}
| improve this answer | |
  • 1
    I would be wary of using the AddBinary methods which do not require a component as they are deprecated or obsolute - check Mihai's excellent blog post: yatb.mitza.net/2012/03/which-addbinary-not-to-use.html – Will Price Sep 5 '13 at 20:50
  • I'm not using one of the obsolete/deprecated methods... I'm passing a null for the related component. The 2011 & 2013 TOM.Net documentation states that it is optional. I have suggested using a related component though. This was just a quick PoC – David Forster Sep 5 '13 at 21:05
  • Ah yes...sorry... then I guess its OK, but I still worry about those unmanaged files, but you mention that! – Will Price Sep 5 '13 at 21:11
  • No worries :) I just edited my answer to remove any ambiguity and confirmed that using null does result in an unmanaged binary – David Forster Sep 5 '13 at 21:12
  • 2
    Instead of using null for the reference multimedia Component, you could consider to just use an existing multimedia Component in your system. It could be a "dummy" multimedia Component or just any reference multimedia Component you determine for this. That way you make sure that at least all your published binaries are managed, and eventually will be cleaned up when everything is unpublished. – Bart Koopman Sep 5 '13 at 22:15
2

I don't think it's possible, to do this whilst in the templating / rendering mode, you might be better off creating a custom resolver to include these files into your published zip package.

Is your website dynamic? We've done something similar in the past where the json is encoded as part of a rendered dynamic page (aspx) and exposed it as part of the page request e.g page.asp?outputtype=json&contentid=3-4567

We didn't want to push files to the server as we'd then had no mechanism to remove them, in this scenario we can un-publish content and keep the server tidy.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.