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

rsc_pivot_done

Signal that a resource pivot has been done.

acl_context_authenticated

Set the context to a typical authenticated user. Used by m_acl.erl

export_resource_visible

mod_export - Check if the resource or dispatch is visible for export.

menu_save

Save the menu tree of a menu resource

auth_confirm

Confirm a user id.

user_context

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

email_ensure_handler

Add a handler for receiving e-mail notifications

acl_logoff

Clear the associated access policy for the context.

mailinglist_mailing

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

postback_event

Message sent by a user-agent on a postback event. Encapsulates the encoded postback and any additional data. This is…

identity_verified

Notification that a user’s identity has been verified.

media_upload_props

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

admin_menu

Used for fetching the menu in the admin.

identity_password_match

Notification that a user’s identity has been verified.

pivot_fields

Foldr to change or add pivot fields for the main pivot table. The rsc contains all rsc properties for this resource

email_status

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

media_identify_file

Try to identify a file, returning a map with file properties.

page_url

Fetch the url of a resource’s html representation

controller_id

Handle different content representations of a page.

cors_headers

Set CORS headers on the HTTP response.

filewatcher

Broadcast some file changed, used for livereload by mod_development

auth_reset

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

media_viewer

Request to generate a HTML media viewer for a resource

media_update_done

Media update done notification. action is ‘insert’, ‘update’ or ‘delete’

media_import

Notification to translate or map a file after upload, before insertion into the database Used in mod_video to queue…

url_abs

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

admin_edit_blocks

Used in the admin to fetch the possible blocks for display

comment_insert

Notification to signal an inserted comment. ‘comment_id’ is the id of the inserted comment, ‘id’ is the id of the…

signup_confirm_redirect

Fetch the page a user is redirected to after signing up with a confirmed identity

signup_check

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

logon_ready_page

Check where to go after a user logs on.

rsc_insert

Foldr for an resource insert, these are the initial properties and will overrule the properties in the insert request.

output_html

Fold for mapping non-iolist output to iolist values. Used when outputting a rendered HTML tree. Folded accumulator is:…

rsc_get

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

multiupload

Handle an uploaded file which is part of a multiple file upload from a user-agent. The upload is a #upload record or a…

media_identify_extension

Try to find a filename extension for a mime type (example: “.jpg”)

sanitize_embed_url

Sanitize an embed url. The hostpart is of the format: <<"youtube.com/v...">> .

email_failed

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

dispatch_host

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

postback_notify

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

acl_user_groups

Return the groups for the current user.

survey_submit

A survey has been filled in and submitted.

export_resource_data

mod_export - fetch a row for the export, can return a list of rows, a binary, and optionally a continuation state.

auth_options_update

Update the given (accumulator) authentication options with the request options. Note that the request options are from…

auth_precheck

First for logon of user with username, check for ratelimit, blocks etc.

Modules

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

logon_submit

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

media_upload_rsc_props

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

signup_done

Signal that a user has been signed up (map, result is ignored)

media_upload_preprocess

Notification to translate or map a file after upload, before insertion into the database Used in mod_video to queue…

import_resource

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

rsc_update_done

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

session_context

Refresh the context or request process for the given request or action Called for every request that is not anonymous…

search_query

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

auth_postcheck

First for logon of user with username, called after successful password check.

activity_send

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

tkvstore_get

Get a value from the typed key/value store

service_authorize

Request API logon

rsc_merge

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

module_activate

A module has been activated and started.

export_resource_header

mod_export - Fetch the header for the export.

ssl_options

Request the SSL certificates for this site. The server_name property contains the hostname used by the client. (first…

content_types_dispatch

Get available content types and their dispatch rules Example: {“text/html”, page} A special dispatch rule is ‘page_url’

import_csv_definition

Find an import definition for a CSV file by checking the filename of the to be imported file.

email_received

Notification sent to a site when e-mail for that site is received

email_add_handler

Add a handler for receiving e-mail notifications

identity_verification

Request to send a verification to the user. Return ok or an error Identity may be undefined, or is a identity used for…

sanitize_element

Sanitize an HTML element.

dropbox_file

Handle a new file received in the ‘files/dropbox’ folder of a site. Unhandled files are deleted after a hour.

auth_logoff

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

pivot_rsc_data

Fold over the resource props map to extend/remove data to be pivoted

category_hierarchy_save

Save (and update) the complete category hierarchy

hierarchy_updated

Signal that the hierarchy underneath a resource has been changed by mod_menu

set_user_language

Set the language of the context to a user’s prefered language

debug

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

Browser/server interaction

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

user_is_enabled

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

survey_is_allowed_results_download

Check if the current user is allowed to download a survey.

auth_checked

Fold over the context after logon of user with username, communicates valid or invalid password

menu_rsc

Fetch the menu id belonging to a certain resource

m_config_update_prop

Site configuration parameter was changed

Notifications

This is a list of all built-in notifications that Zotonic sends. Observe these notifications in your code to add custom…

custom_pivot

Add custom pivot fields to a resource’s search index (map) Result is a list of {module, props} pairs. This will update…

signup_confirm

Signal that a user has been confirmed. (map, result is ignored)

export_resource_footer

mod_export - Fetch the footer for the export. Should cleanup the continuation state, if needed.

auth_confirm_done

A user id has been confirmed.

acl_is_allowed_prop

Check if a user is authorizded to perform an action on a property. Defaults to true .

email_bounced

Bounced e-mail notification. The recipient is the e-mail that is bouncing. When the the message_nr is unknown the it…

acl_is_owner

Check if a user is the owner of a resource. id is the resource id.

mailinglist_message

Send a welcome or goodbye message to the given recipient. The recipient is either an e-mail address or a resource id.

auth_validate

First to validate a password. Return {ok, RscId} or {error, Reason}.

request_context

Refresh the context or request process for the given request or action Called for every request that is not anonymous…

edge_delete

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

acl_logon

Initialize context with the access policy for the user.

rsc_upload

Upload and replace the resource with the given data. The data is in the given format. Return {ok, Id} or {error

debug_stream

Internal message of mod_development. Start a stream with debug information to the user agent. ‘target’ is the id of the…

export_resource_filename

mod_export - return the {ok, Filename} for the content disposition.

auth_logon

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

Overriding Zotonic

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

edge_update

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

rsc_delete

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

signup_url

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

survey_get_handlers

Fetch list of handlers for survey submits.

email_sent

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

media_replace_file

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

email_is_blocked

Check if an email address is blocked

scomp_script_render

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

rsc_query_item

Send a notification that the resource ‘id’ is added to the query query_id.

media_stillimage

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

tkvstore_put

Put a value into the typed key/value store

acl_mqtt

MQTT acl check, called via the normal acl notifications. Actions for these checks: subscribe, publish

dispatch

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

m_config_update

Site configuration parameter was changed

signup

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

edge_insert

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

signup_failed_url

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

rsc_update

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

url_rewrite

Rewrite a URL after it has been generated using the z_dispatcher

survey_is_submit

Check if a question is a submitting question.

media_import_props

Notification to translate or map a file after upload, before insertion into the database Used in mod_video to queue…

tkvstore_delete

Delete a value from the typed key/value store

pivot_update

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

admin_rscform

Used in the admin to process a submitted resource form

export_resource_content_disposition

mod_export - return the {ok, Disposition} for the content disposition.

dispatch_rewrite

Rewrite a URL before it will be dispatched using the z_sites_dispatcher

language

Notify that the session’s language has been changed

export_resource_encode

mod_export - Encode a single data element.

acl_is_allowed

Check if a user is authorized to perform an operation on a an object (some resource or module). Observe this…

activity

An activity in Zotonic. When this is handled as a notification then return a list of patterns matching this activity.

module_deactivate

A module has been stopped and deactivated.

auth_validated

Authentication against some (external or internal) service was validated

email_drop_handler

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

action_event_type

Render the javascript for a custom action event type. The custom event type must be a tuple, for example: {% wire…

postback

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

security_headers

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

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…

media_preview_options

Modify the options for an image preview url or tag. This is called for every image url generation, except if the…

auth_client_logon_user

Send a request to the client to login an user. The zotonic.auth.worker.js will send a request to…

url_fetch_options

Determine the URL fetch options for fetching the content of an URL. Used by z_fetch.erl.

media_import_medium

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

resource_headers

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

validate_query_args

Called just before validation of all query arguments by z_validation. This is the moment to filter any illegal…

email_dkim_options

Return the options for the DKIM signature on outgoing emails. Called during email encoding.

auth_client_switch_user

Send a request to the client to switch users. The zotonic.auth.worker.js will send a request to…

logon_options

Check for logon options, called if logon_submit returns undefined . This is used to fetch external (or local…

http_log_access

Access log event for http. Called from the z_stats.

email_send_encoded

Add a handler for receiving e-mail notifications

rsc_import_fetch

Fetch the data for an import of a resource. Returns data in the format used by m_rsc_export and m_rsc_import.

middleware

Delegates the request processing.