8

I'm working with Tridion 2009. When I publish a component I expect that it will be publish the dynamic components template related. But, it is also publishing the components where is used. I have a component that takes 20 minutes to publish because it is being used in several components. To solve this problem, I have implemented a custom resolver to try to publish just the component that I wish... I get it! :) but the component still takes 20 minutes to publish...

How can I render & publish just the component that I want?

I add my code maybe it will help:

public class GetElementsToPublish : IResolver
    {
        public const string SCHEMA_SEO = "164";

        public void Resolve(IdentifiableObject item, ResolveInstruction instruction, PublishContext context, Tridion.Collections.ISet<ResolvedItem> resolvedItems) {
            if (item is Component)
            {
                Component component = (Component)item;
                switch (component.Schema.Id.ItemId.ToString())
                {

                    case (SCHEMA_SEO):
                        //instruction.IncludeComponentLinks = false;
                       SeoResolver.**GetComponentsToPublishBySEO**(resolvedItems, item);
                        break;
                }
            }
        } 
    }




public class SeoResolver
    {
        //No me interesa que publique nada del "where is used"
        public static Tridion.Collections.ISet<ResolvedItem> GetComponentsToPublishBySEO(Tridion.Collections.ISet<ResolvedItem> resolvedItems, IdentifiableObject item)
        {
            List<ResolvedItem> addItems = new List<ResolvedItem>();
            foreach (ResolvedItem itemR in resolvedItems)
            {
                if (itemR.Item.Id.ItemId.Equals(item.Id.ItemId))
                {
                    addItems.Add(itemR);
                }
            }
            foreach (ResolvedItem addItem in addItems)
            {
                resolvedItems.Remove(addItem);
            }
            return resolvedItems; 
        }
    }

After the component has been published, I can see just the component that I want has been successfully published. But, when I check the "see items to publish" the related components are still there... :( Thank you!

9

It sounds like your custom resolver is not working - you can check which items are going to be published by clicking the See Items to Publish button on the bottom left of the publish popup - if your resolver is working this will only show the one component. If you want to debug your resolver, then attach to the publisher process (TcmPublisher.exe - I think) when you are publishing the component (if you have Visual Studio installed on the publisher server, or are lucky enough to have managed to get remote debugging working with Visual Studio).

EDIT Now that you have posted the code and state that the see items to publish shows all the components it is clear there is a problem with your logic. The Resolve method is void, and what you should be doing is clearing all unwanted items from the resolvedItems parameter. It looks like you are simply removing the item that you actually want from resolvedItems, leaving all the other stuff in there.

Try something like this:

resolvedItems.Clear();
foreach (ResolvedItem resolvedItem in addItems)
{
    resolvedItems.Add(resolvedItem);
}

If you are still having problems refer to this answer for a full working resolver example:

  • 1
    with regards to debugging the resolver, you can also attach to the TcmServiceHost and the w3wp.exe processes to debug it while you click on the See Items to Publish button – Bart Koopman May 28 '13 at 7:58
  • ohhh!! :( It's true! let me try what you said! :) – Aroma May 28 '13 at 8:52
  • 1
    Apart from clearing the entire collection and rebuilding it with only the items you need, you could also just remove those you don't want. But it is important to not try to remove those items in the same loop you use to identify them (as that never works), here is an example of a Resolver I used to strip out items from a parent Publication gist.github.com/bkoopman/5662079 – Bart Koopman May 28 '13 at 11:30
4

You need to disable link propagation, so no components that are using this component will be republished.

You control that using the Event System before the publishing.

For 2011 you have to do call to a method that implements that Example: When you initialize the Event

    private void InitializeEvent()
    {
        EventSystem.Subscribe<Component, PublishEventArgs>(DisableLinkPropagation, EventPhases.Initiated);
    }

//The code of the Method for disable link propagation is
    private void DisableLinkPropagation(Component component, PublishEventArgs args, EventPhases phases)
    {
        if(IsLinkDisabled(component))
            args.PublishInstruction.ResolveInstruction.IncludeComponentLinks = false;
    }

In your case, as is 2009 you have to do that with the previous version of the Event System, and code that in the event onComponentPublishPre. The concept is similar, you have change the publish instruction for set the parameter that triggers the link propagation to false, bus in this case is not accessible via API, so you change the XML of the publish instruction

void _ITCMEvents.OnComponentPublishPre(Component Component, IXMLDOMDocument2 publishInstruction)
{
    IXMLDOMElement root = publishInstruction.documentElement;
    IXMLDOMNode resolveComponentLinks = publishInstruction.selectSingleNode("//*[local-name()='ResolveComponentLinks']");
    if (resolveComponentLinks == null)
    {
        resolveComponentLinks = publishInstruction.createNode(1, "tcm:ResolveComponentLinks", "http://www.tridion.com/ContentManager/5.0");
        root.appendChild(resolveComponentLinks);
    }
    resolveComponentLinks.text = bool.FalseString.ToLower();
}
0

Custom resolver is the best option to resolve your issue and you have adopted the best approach to resolve the issue. As @Will has stated the issue could be your custom resolver might not be working or there might be some code related issue which is not getting executed the way you want it to be.

Nevertheless, I would like to share one practical resolution apart from Custom Resolver that we have to do (this solution only suits our specific scenario due to multiple reasons and that we could not use Custom Resolver).

The Scenario: It was for a Heating & Cooling company where we have to showcase their different products and for each products there could be numerous related products - For example, weareshowing one Air Conditioner and along with it we are showing numerous other related ACs and its accessories.

In this scenario where we have to linked with numerous components, instead of linking with actual components, we tweak it to use Keywords to create a bridge between the two component - Kind of Primary-Foreign Key relationship. In this way since there is no actual link to the linked component, it will not publish any additional component. The linking can be achieved using Content Delivery on the basis of keyword mapping and querying the broker accordingly.

PS:

I know there could be better solution, but this solution was the demand of the situation (and of course an alternate for all the so called best solution)

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.