6

I am trying to create a new template block which checks all text fields of a component(recursevely with a specified link-levels property), try to find linked components, get their URIs and publish the component into the package.

The problem is that when I try my block with the Template Builder everything looks nice, but when I republish my page the component is not published. I can not see it into Component or Items relation tables into the broker.

Do you have any suggestions?

tempalte builder

Part of my code:

public override void Transform(global::Tridion.ContentManager.Templating.Engine engine, 
    global::Tridion.ContentManager.Templating.Package package)
{
    ...
    // get the page
    Page page = GetPage();

    ...

    LoadItemFields(......);
}

private void LoadItemFields(...)
{
    ...

    TextField text = item as TextField;
    if (text != null)
    {
        // get the URIs of the linked components and puch the components into the package
        var uRIs = RichTextHelper.ResolveRichText(text.Value);
        foreach (var line in uRIs)
        {
            Logger.Info("Push a component into the package.");
            var component = m_Package.CreateTridionItem(ContentType.Component, new TcmUri(line));
            if (component != null)
                m_Package.PushItem("component:" + line, component);
        }

        continue;
    }

    ...
}
9

Adding component to the package does not necessary mean it will get published.

I would suggest you to write a custom resolver that will check components and add related components to resolved items. This way related items will be published as well.

| improve this answer | |
  • +1, Chris Summers explains templates "read only" default scenario. He describes custom resolvers and alternatives including a config change (read the warning) and core service approach on TridionDeveloper. – Alvin Reyes Jun 14 '13 at 21:57
2

There is an easy way to accomplish that by using the AddRenderedItem method.

Here a sample:

Component componentToBePublished = GetComponentToBePublished();
ComponentTemplate templateToBePublished = GetTemplateToBePublished();

RenderInstruction renderInstruction = engine.PublishingContext.RenderedItem.RenderInstruction;
RenderedItem itemToRender = new RenderedItem(new ResolvedItem(componentToBePublished, templateToBePublished), renderInstruction);

engine.PublishingContext.RenderedItem.AddRenderedItem(itemToRender);

This code will instruct the Resolvers to include that component in the Publishing Instructions.

| improve this answer | |
1

By Default: If you are publishing a Component, all the pages, this component is included on will get published. However, on the other hand if you publish a page, the component included on it will not get publish. This is the defult and logical behaviour of SDL Tridion.

To achieve this you can opt for any of following approach based on your business need (and in the order of their recommendations):

  1. Use a custom resolver and write custom code to retrieve all the components available on the page and programatically publish them all. You can google to find lots of available guidance on Custom Resolver

  2. Make use of event system - You may want to write something like this:

    private void Subscribe() { EventSystem.SubscribeAsync(PagePublishAllComponents, EventPhases.TransactionCommitted); }

      private static void PagePublishAllComponents(Page subject, PublishEventArgs args, EventPhases phase)
      {
          PublishInstruction pubInstruction = args.PublishInstruction;
          if (pubInstruction.ResolveInstruction.Purpose == ResolvePurpose.Publish)
          {
              // get the current publication transaction 
              PublishPriority pubPriority = (PublishPriority)args.Priority;
              List<TargetType> targets = new List<TargetType>();
              IEnumerable<PublishingTarget> pubTargets = args.Targets;
              IEnumerator<PublishingTarget> enumPubTarget = pubTargets.GetEnumerator();
              while (enumPubTarget.MoveNext())
              {
                  TargetType curpubtarget = (TargetType)enumPubTarget.Current;
                  targets.Add(new TargetType(curpubtarget.Id, subject.Session));
              }
              try
              {
                  PublishEngine.Publish(items, pubInstruction, targets, pubPriority);
              }
              catch (PublisherException pe)
              {
                  //Exception here
              }
          }
          else
          {
              log.Info("No components need to be published from the page..");
          }
    
      }
    
  3. If you want to publish pages and all its component in one single transaction (per your comment), then you can take advantage of Storage Extension and from there you call a WCF service wrapper for Core Service (or may be Core Service directly) and pass it the WebDav URL of the page. In the service you may write code to retrieve the components being used in the page and publish them NOTE: In storage extension for a page publishing, you will NOT be able to retrieve the Components included on the page straight forwardly

| improve this answer | |
  • In your sceond point you are creating a separate publish transaction. It means that your page may be partially published. – Andrey Marchuk Jun 14 '13 at 13:46
  • Based on your business need, you may change the Event Phase. I have shared the code which was written per our business need and I have trimmed down it before posting here. If you want to keep it in same publishing transaction then see the 3rd Option mentioned in the answer. – Pankaj Gaur Jun 14 '13 at 14:13
  • 1
    Careful with the first paragraph. Not all pages are published, specifically items that use the item queued for publishing are re-published. So non-published pages ("in development") don't get published. Also publishing a page does publishes any "dynamic" component presentations on it. – Alvin Reyes Jun 14 '13 at 21:37

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.