MishkaCmsCore.Runtime.Resources.Notifiers.PluginHook (Mishka CMS Core v0.0.1)

Copy Markdown View Source

A reusable Ash notifier that emits a MishkaInstaller plugin event after every action (create / update / destroy, including custom-named actions) on any resource it is added to.

Add it to a resource's notifier list — and because it lives in mishka_cms_core (a dependency of every extension), all extensions share the exact same hook mechanism:

use Ash.Resource,
  ...,
  notifiers: [Ash.Notifier.PubSub, MishkaCmsCore.Runtime.Resources.Notifiers.PluginHook]

It fires "<app>:<resource>:after_<action>" — e.g. "blog:comment:after_create", "blog:post_rating:after_remove", "document:section:after_update" — handing the resulting record to plugins, plus a read-only meta: %{actor:, site_id:}.

A plugin that listens on one of these names its event with event_name/2 rather than spelling the string, so the name it listens on is the name fired:

use MishkaInstaller.Event.Hook,
  event: PluginHook.event_name(MishkaBlog.BlogPost, :publish)

One event is one action. A master user runs the action's master_* twin, which fires its own event ("blog:blog_post:after_master_publish"), so reacting to both takes a plugin on each.

After any save

A create or update action — whatever its name, a master's twin included — also fires "<app>:<resource>:after_save" (save_event_name/1), after its own event, with the same record and meta. A plugin that reacts to the record being written, however it was written, listens there once:

use MishkaInstaller.Event.Hook, event: PluginHook.save_event_name(MishkaBlog.BlogPost)

Because notifiers run after the transaction commits, the action stays atomic — adding this changes no authorization or atomicity behaviour (no require_atomic? false, no 403→404). This is why it works uniformly for destroy actions too.

For before/reject seams (which a notifier cannot do), use a before_action change on the specific action instead. See MishkaInstaller.Event.Hook.

Summary

Functions

The event this notifier fires when action_name runs on resource: event_name(MishkaBlog.BlogPost, :publish) is "blog:blog_post:after_publish".

The event fired after any create or update action on resource: save_event_name(MishkaBlog.BlogPost) is "blog:blog_post:after_save".

Functions

event_name(resource, action_name)

@spec event_name(module(), atom()) :: String.t()

The event this notifier fires when action_name runs on resource: event_name(MishkaBlog.BlogPost, :publish) is "blog:blog_post:after_publish".

save_event_name(resource)

@spec save_event_name(module()) :: String.t()

The event fired after any create or update action on resource: save_event_name(MishkaBlog.BlogPost) is "blog:blog_post:after_save".