Notifications

At different moments in the lifecycle of the web request, Zotonic sends notifications. By observing these notifications you can override Zotonic’s behaviour. You can also add your own notifications.

Zotonic’s notifier system makes it possible to create modular components with a pluggable interface. The notifier system is used by internal core Zotonic components like the authentication mechanism, the logging system and more.

The notification system can not only act as a traditional event subscription system but also as an advanced priority based function dispatch system. It uses the same priority system which is used to select templates. This makes it possible to override pre-defined default behaviour of core Zotonic modules.

A notification message is a tagged tuple. The first element of the tuple is the type of notification message. An observer can use this to subscribe to specific messages it is interested in.

Example:

{acl_logon, 1234}

Or:

{module_activate, mod_stream, <0.32.0>}

You can find a list of all notifications in the reference section.

Sending notifications

As mentioned earlier, the notification system can not only be used to just send events to observers. Observers can also return values back. They can do this in various ways described in the methods below.

Notification types

notify

Send a message to all observers. This is used if you want to notify other observers about a specific event. In Zotonic this is used a lot. For instance, it is used to notify modules of about user logons, or notify when modules are activated and deactivated.

notify1

Notify the first observer. This is useful for if you want to be sure just one observer can do something with the message.

first

Call all observers, and use the first non undefined answer. This is used to get information from one of the observers. By using the notification system it makes sure that modules are decoupled.

map

Call all observers and get a list of all answers.

foldl

Do a fold over all observers, high prio observers first.

foldr

Do a fold over all observers, low prio observers first.

notify_sync

Synchronous notification, wait till all observers have processed the notification before continuing. The notify will notify all observers asynchronously and returns before all notifications are processed.

The synchronous notification also shares the current database transaction (if any) and other context data with the observers. This allows to process the notification within a transaction.

Subscribing to notifications

Registering as an observer works as follows:

z_notifier:observe(NotificationType, Handler, Priority, Context)

If the module is either a Zotonic module or a site module, the Priority parameter can be omitted. The observer will then get the same priority as the module.

NotificationType
The type of notification you want to observe, an atom.
Handler
Can be a pid(), or a {Module, Fun} tuple. When the handler is a pid() and the notification is sent with notify or notify1 the gen_server process receives a handle_cast. When an answer is expected back handle_call is used. This is the case for first, map, foldl and foldr.
Priority
The priority of the observer. This influences the order in which they are called.
Context
The Zotonic context.

Example:

z_notifier:observe(acl_logon, {mysitewww, handle_logon}, Context)

Subscription shorthands

Modules and sites can use shortcuts for registering as an observer. When the Zotonic module exports a function with the prefix observe_ or pid_observe_ Zotonic’s module manager will register the observer for you.

For example exporting observe_acl_logon/2 will register that function as an observer. It will be triggered when the acl_logon notification is fired. Functions prefixed with pid_observe_ are for gen_server based modules: they get passed the gen_server’s PID as the first argument.

Handling notifications

When a notifications is sent the z_notifier module looks in its tables to see if there are any observers interested in receiving it. There are three types of notifications.

Cast notifications

This is the simplest notification. The notifier does not expect an answer back the result of the handler is ignored. This kind of notification is triggered by calling z_notifier:notify/2 or z_notifier:notify1/2. They are useful for letting other modules know about a certain even or condition. This makes it possible for other modules to act on it.

For example, mod_development uses call notifications to trigger builds and reloads. By doing this other modules can notify mod_development to trigger builds. But when mod_development is disabled nothing will happen.

Call notification

For this kind of notification, z_notifier expects an answer back. This answer is returned back to the notifier. This kind of notifications is used to decouple modules. For instance a module can ask another module for a special URL to go to after logging in without knowing which module will do this. Call notifications are triggered by: z_notifier:first/2 and z_notifier:map/2.

For example, mod_signup uses a call notification to find out what page to redirect to after a successfull signup. This allows one to customize the signup process.

Fold notifications

Fold notifications are called, with z_notifier:foldl/3 or z_notifier:foldr/3. It works similarly to the lists:foldr and lists:foldl functions of Erlang’s lists module. The fold function calls each observer in sequence, either starting at highest (foldl) or at lowest (foldr) priority, passing values and an initial accumulator value. Each observer can adapt values in the accumulator, and needs to return it, for passing on to the next observer. The final value of the accumulator is returned as result. This is useful if you want multiple modules to be able to adapt and use values in the accumulator. For example, mod_admin uses a fold notification (called admin_menu) to build up the admin navigation menu, where each observer is called to add menu entries to the menu.

Modules Developer Guide Browser/server interaction

Referred by

Notifications

observe_user_context/3

Set #context fields depending on the user and/or the preferences of the user.

Notifications

observe_mailinglist_mailing/2

Send a page to a mailinglist (notify) Use {single_test_address, Email} when sending to a specific e-mail address.

Notifications

observe_identity_verified/2

Notify that a user’s identity has been verified. Signals to modules handling identities to mark this identity as verified. Handled by mod_admin_identity to…

Notifications

observe_media_upload_props/3

Notification that a medium file has been uploaded. This is the moment to change properties, modify the file etc. The folded accumulator is the map with updated…

Notifications

observe_pivot_fields/3

Foldr to change or add pivot fields for the main pivot table. The rsc contains all rsc properties for this resource, including pivot properties. Fold with a…

Notifications

observe_email_status/2

Email status notification, sent when the validity of an email recipient changes

Controllers

controller_id

Handle different content representations of a page.

Notifications

observe_filewatcher/2

Broadcast some file changed, used for livereload by mod_development

Notifications

observe_auth_reset/2

First to check for password reset forms, return undefined, ok, or {error, Reason}.

Notifications

observe_media_viewer/2

Request to generate a HTML media viewer for a resource. The HTML data can not contain any Javascript, as it might be serialized. This could happen if the…

Notifications

observe_media_import/2

Notification to translate or map a file after upload, before insertion into the database Used in mod_video to queue movies for conversion to mp4. You can set…

Notifications

observe_url_abs/2

Make a generated URL absolute, optionally called after url_rewrite by z_dispatcher

Notifications

observe_comment_insert/2

Notification to signal an inserted comment. ‘comment_id’ is the id of the inserted comment, ‘id’ is the id of the resource commented on.

Notifications

observe_signup_check/3

signup_check Check if the signup can be handled, a fold over all modules. Fold argument/result is {ok, Props, SignupProps} or {error, Reason}

Notifications

observe_rsc_insert/3

Foldr for a resource insert, these are the initial properties and will overrule the properties in the insert request. Use with care. The props are the…

Notifications

observe_rsc_get/3

Resource is read, opportunity to add computed fields Used in a foldr with the read properties as accumulator.

Notifications

observe_email_failed/2

Notify that we could NOT send an e-mail (there might be a bounce later...) The Context is the depickled z_email:send/2 context.

Notifications

observe_dispatch_host/2

Try to find the site for the request Called when the request Host doesn’t match any active site.

Notifications

observe_postback_notify/2

Handle a javascript notification from the postback handler. The message is the the request, trigger the id of the element which triggered the postback, and…

Notifications

observe_export_resource_data/2

mod_export - fetch a row for the export, can return a list of rows, a binary, and optionally a continuation state. Where Values is [ term() ], i.e. a list of…

Developer guide

Modules

Modules are the building blocks of Zotonic. They add functionality to your Zotonic website such as:

Notifications

observe_logon_submit/2

Handle a user logon. The posted query args are included. Return:: {ok, UserId} or {error, Reason}

Notifications

observe_media_upload_rsc_props/3

Notification that a medium file has been uploaded. This is the moment to change resource properties, modify the file etc. The folded accumulator is the map…

Notifications

observe_media_upload_preprocess/2

Notification to translate or map a file after upload, before insertion into the database Used in mod_video to queue movies for conversion to mp4. You can set…

Notifications

observe_import_resource/2

An external feed delivered a resource. First handler can import it. Return:: {ok, m_rsc:resource_id()} , {error, Reason} , or undefined

Notifications

observe_rsc_update_done/2

An updated resource has just been persisted. Observe this notification to execute follow-up actions for a resource update.

Notifications

observe_activity_send/2

Push a list of activities via a ‘channel’ (eg ‘email’) to a recipient. The activities are a list of #activity{} records.

Notifications

observe_rsc_merge/2

Map to signal merging two resources. Move any information from the loser to the winner. The loser will be deleted.

Notifications

observe_ssl_options/2

Request the SSL certificates for this site. The server_name property contains the hostname used by the client. (first) Returns either ‘undefined’ or a list of…

Notifications

observe_content_types_dispatch/3

Get available content types and their dispatch rules Example: {{<<”text”>>, <<”html”>>, []}, page} A special dispatch rule is ‘page_url’, which refers to the…

Notifications

observe_identity_verification/2

Request to send a verification to the user. Return ok or an error. Handled by mod_signup to send out verification emails. Identity may be undefined, or is an…

Notifications

observe_dropbox_file/2

Handle a new file received in the ‘files/dropbox’ folder of a site. Unhandled files are deleted after an hour. If the handler returns ‘ok’ then the file is…

Notifications

observe_auth_logoff/3

User is about to log off. Modify (if needed) the logoff request context.

Notifications

observe_debug/2

Push some information to the debug page in the user-agent. Will be displayed with io_lib:format(“~p: p n”, [What, Arg]), be careful with escaping information!

Developer guide

Browser/server interaction

There are multiple ways to set up interaction between server-side Zotonic code and client-side JavaScript.

Notifications

observe_user_is_enabled/2

Check if a user is enabled. Enabled users are allowed to log in. Return true , false or undefined . If undefined is returned, the user is considered enabled if…

Notifications

observe_auth_checked/2

Notify after logon of user with username, communicates valid or invalid password

Category

Notifications

Messages exchanged between Zotonic components to observe events, request data, or alter behavior.

Notifications

observe_custom_pivot/2

Add custom pivot fields to a resource’s search index (map) Result is a single tuple or list of tuples {pivotname, props} , where “pivotname” is the pivot…

Notifications

observe_email_bounced/2

Bounced e-mail notification. The recipient is the e-mail that is bouncing. When the the message_nr is unknown the it is set to ‘undefined’. This can happen if…

Notifications

observe_mailinglist_message/2

Send a welcome or goodbye message to the given recipient. The recipient is either a recipient-id or a recipient props. ‘what’ is send_welcome, send_confirm

Notifications

observe_edge_delete/2

An edge has been deleted Note that the Context for this notification does not have the user who deleted the edge.

Notifications

observe_rsc_upload/2

Upload and replace the resource with the given data. The data is in the given format.

Notifications

observe_auth_logon/3

User logs on. Add user-related properties to the logon request context.

Cook book

Overriding Zotonic

This chapter describes how to override the templates, styling and logic provided by Zotonic.

Notifications

observe_edge_update/2

An edge has been updated Note that the Context for this notification does not have the user who updated the edge.

Notifications

observe_rsc_delete/2

Resource will be deleted. This notification is part of the delete transaction, it’s purpose is to clean up associated data.

Notifications

observe_signup_url/2

Handle a signup of a user, return the follow on page for after the signup. Return {ok, Url} ‘props’ is a map with properties for the person resource (email

Notifications

observe_email_sent/2

Notify that we could NOT send an e-mail (there might be a bounce later...) The Context is the depickled z_email:send/2 context.

Notifications

observe_media_replace_file/2

Notification that a medium file has been changed (notify) The id is the resource id, medium contains the medium’s complete property map.

Notifications

observe_scomp_script_render/2

Add extra javascript with the {% script %} tag. (map) Used to let modules inject extra javascript depending on the arguments of the {% script %} tag. Must…

Notifications

observe_media_stillimage/2

See if there is a ‘still’ image preview of a media item. (eg posterframe of a movie) Return:: {ok, ResourceId} or undefined

Notifications

observe_dispatch/2

Final try for dispatch, try to match the request. Called when the site is known, but no match is found for the path

Notifications

observe_signup/2

Request a signup of a new or existing user. Arguments are similar to #signup_url{} Returns {ok, UserId} or {error, Reason}

Notifications

observe_edge_insert/2

An edge has been inserted. Note that the Context for this notification does not have the user who created the edge.

Notifications

observe_signup_failed_url/2

Signup failed, give the error page URL. Return {ok, Url} or undefined. Reason is returned by the signup handler for the particular signup method (username

Notifications

observe_rsc_update/3

An updated resource is about to be persisted. Observe this notification to change the resource properties before they are persisted.

Notifications

observe_pivot_update/3

Pivot just before a m_rsc_update update. Used to pivot fields before the pivot itself.

Notifications

observe_acl_is_allowed/2

Check if a user is authorized to perform an operation on a an object (some resource or module). Observe this notification to do complex or more fine-grained…

Notifications

observe_activity/2

An activity in Zotonic. When this is handled as a notification then return a list of patterns matching this activity. These patterns are then used to find…

Notifications

observe_email_drop_handler/2

Drop an e-mail handler for a user/resource id. (notify). The notification, user and resource should be the same as when the handler was registered.

Notifications

observe_action_event_type/2

Render the javascript for a custom action event type. The custom event type must be a tuple, for example: {% wire type={live id=myid} action={...} %}</code>…

Validators

postback

Performs a custom server side validation of an input value. This allows you to add your own validation logic to HTML form fields.

Notifications

observe_security_headers/2

Check and possibly modify the http response security headers All headers are in lowercase.

Controllers

controller_logon_done

This controller is used as a jumping stone after a log on from the /logon page. The p argument is passed from the /logon page.

Notifications

observe_media_preview_options/3

Modify the options for an image preview url or tag. This is called for every image url generation, except if the ‘original’ image option is passed. The…

Notifications

observe_media_import_medium/2

Notification to import a medium record from external source. This is called for non-file medium records, for example embedded video. If the medium record is…

Notifications

observe_resource_headers/3

Let all modules add resource specific response headers to the request. The accumulator is the list of headers to be set.

Notifications

observe_logon_options/3

Check for logon options, called if logon_submit returns undefined. This is used to fetch external (or local) authentication links for a username. Return:: map()

Notifications

observe_rsc_import_fetch/2

Fetch the data for an import of a resource. Returns data in the format used by m_rsc_export and m_rsc_import. Either returns the JSON data, the imported…

Notifications

observe_acl_user_groups_modify/3

Modify the list of user groups of a user. Called internally by the ACL modules when fetching the list of user groups a user is member of.

Notifications

observe_media_viewer_consent/2

Optionally wrap HTML with external content so that it adheres to the cookie/privacy settings of the current site visitor. Typically called with a ‘first’ by…

Notifications

observe_acl_collab_groups_modify/3

Modify the list of collaboration groups of a user. Called internally by the ACL modules when fetching the list of collaboration groups a user is member of.

Notifications

observe_survey_result_column_values/3

Modify row with answers for export. The header columns are given and the values that are known are set in the folded value. The user_id is the user who filled…

Notifications

observe_survey_result_columns/3

Add header columns for export. The values are the names of the answers and the text displayed above the column. The text format is for a complete export, the…

Notifications

observe_translate/2

Request a translation of a list of strings. The resulting translations must be in the same order as the request. This notification is handled by modules that…

Notifications

observe_language_detect/2

Try to detect the language of a translation. Set is_editable_only to false to detect any language, even if the language is not enabled for the site. Return…

Notifications

observe_auth_identity_types/3

Return the list of identity types that allow somebody to logon and become an active user of the system. Defaults to [ username_pw ]. In the future more types…

Notifications

observe_email_is_recipient_ok/2

Check if an email address is safe to send email to. The email address is not blocked and is not marked as bouncing.