Disabling a Publication Target for a Structure Group

15

Is there any way of disabling publishing to a Publication Target within a specific Structure Group?

One of our clients is about to relaunch a section of their site, and we need to restructure the layout of this section as part of the deployment process. We want to disable live publishing during this. As this process may take a day or two, it would be nice to allow publishing of other sections of the site.

We can't disable publishing for the Structure Group using the "Publishable" property as we still need to publish and preview content in staging.

Whilst we'll be informing them of a live-publishing freeze, I was wondering if there was a way this could be enforced?

richeym

Posted 2013-03-19T13:50:24.827

Reputation: 327

Answers

11

As far as I know there's nothing out of the box that does this, and seeing that you cannot uncheck the "Publishable" property, a GUI extension might be the way to go.

Here's a good post from Jaime Santos that talks about removing publication targets that might help you out.

http://jaimesantosalcon.blogspot.com/2011/10/2011-sdl-tridion-gui-extensions.html

Ibrar Hussain

Posted 2013-03-19T13:50:24.827

Reputation: 1 458

10

You could write a custom resolver (or an events system) that removed the relevant items. It's probably not that hard. Here's a quick sketch:

public class TemporaryFilter : IResolver
{        
    public void Resolve(IdentifiableObject item, ResolveInstruction instruction, PublishContext context, ISet<ResolvedItem> resolvedItems)
    {
        ISet<ResolvedItem> filteredItems = new HashSet<ResolvedItem>();
        OrganizationalItem sgNotToPublish = (OrganizationalItem)item.Session.GetObject("tcm:foobar");
        foreach (ResolvedItem resolvedItem in resolvedItems)
        {
            if (resolvedItem.PublicationTarget.Id != "tcm:blah")
            {
                if (!((RepositoryLocalObject)resolvedItem.Item).GetAncestors().Contains(sgNotToPublish))
                {
                    filteredItems.Add(resolvedItem);
                }
            }
        }
        resolvedItems.Clear();
        foreach (ResolvedItem filteredItem in filteredItems)
        {
            resolvedItems.Add(filteredItem);
        }
    }
}

Dominic Cronin

Posted 2013-03-19T13:50:24.827

Reputation: 14 997

7

If you don't have any TBBs that publish binaries to a specific SG, then you only need to worry about restricting the publishing of Pages in an SG. For this you may implement a very simple page-level TBB that checks what structure group the Page is being published to and throws an exception with a clear message. Put this TBB into your Default Finish Actions or include in every PT:

public class RestrictPublishingToSG : ITemplate
{
    private TemplatingLogger logger = null;

    public void Transform(Engine engine, Package package)
    {
        logger = TemplatingLogger.GetLogger(this.GetType());

        Page page = engine.GetObject(package.GetValue("Page.ID")) as Page;

        if(page == null)
        {
            return; // do nothing if rendering an item that's not a page
        }

        string[] restrictedSGIds = package.GetValue("RestrictedStructureGroupIDs").Split(new char[]{','});  //get the list of comma-separated SG IDs from Parameters schema
        foreach (string restrictedSGiD in restrictedSGIds)
        {
            if (page.OwningRepository.Id.ToString() == restrictedSGiD)
            {
                throw new Exception("Publishing to this SG has been restricted.  Publishing aborted");
            }
        }
    }
}

Nickoli Roussakov

Posted 2013-03-19T13:50:24.827

Reputation: 16 339

6

You can remove read on the structure group. Editors can't directly publish pages they can't find in the Content Manager Explorer (see caveat below).

Other practical alternatives include:

  • communicating the situation to the editors (maybe also adding a "do not publish" to the structure groups names)
  • copying and pasting pages and publishing the new ones; though you lose page history, components remain intact
  • if old pages need to redirect to the new ones, leave the existing pages and update them to point to their new locations (JavaScript or server-side redirect)

Resolving Behavior

To handle this completely, a Custom Resolver could catch scenarios where components could trigger these pages. See the "Items that can be published, republished, or unpublished" (requires login) for the relevant cases, mainly publishing an item causes items that use it to be republished. Specifically in this situation, publishing components embedded on a page will cause the page to be republished.

You might have to remove component presentations and/or prevent authors from publishing certain components during this process as well.

Alvin Reyes

Posted 2013-03-19T13:50:24.827

Reputation: 8 870