Event System handler code:
[TcmExtension("My Handler")]
public sealed class EventSystem : TcmExtension
{
public EventSystem()
{
EventSystem.Subscribe<Page, PublishEventArgs>((page, e, phases) => {
if (shouldTerminatePublishing(page))
{
throw new Exception(ex, page);
}
}, EventPhases.Initiated, EventSubscriptionOrder.Normal);
}
}
With the code above when multiple pages are being published and Event System is only about to block one of them (by throwing an exception), then all pages are effectively prevented from being published too. "Ignore Failures While Generating Publishable Content" check box does not affect this behavior.
How to prevent any given page from publishing but still allow all the rest to be published?
EDIT
Updated code as per Quirijn's suggestion:
public class MyResolver: IResolver
{
public void Resolve(
IdentifiableObject item,
ResolveInstruction instruction,
PublishContext context,
ISet<ResolvedItem> resolvedItems)
{
var page = item as Page;
if (null != page && instruction.Purpose == ResolvePurpose.Publish)
{
try
{
// Evaluate whether publishing is allowed
}
catch (Exception ex)
{
resolvedItems.Clear();
}
}
}
}
Some objections (or rather follow-up questions) so far:
- There's no sensible way to provide explicit feedback to the user when item gets excluded (except advising to check "Show Items to Publish" option), is there?
- Custom resolver must explicitly account for all items types, that is: not only for 'Page' but also 'StructureGroup' and 'Publication', must it not?
- Given that evaluation code might be expensive (web service call), is there any way to cache it's result at least between preparing "Show Items to Publish" list and performing actual publishing? (In such case evaluation occurs at least twice).
EDIT 2
After looking into standard resolvers' implementation:
- Is it necessary/preferably to implement IBulkResolver as well?