PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 15ms RepoModel.GetById 2ms app.codeStats 0ms

/modules/mod_signal/z_connect.erl

http://github.com/zotonic/zotonic
Erlang | 70 lines | 31 code | 10 blank | 29 comment | 2 complexity | 9e365842d3f6b689bedd6a7a3508a4ca MD5 | raw file
 1%% @author Maas-Maarten Zeeman <mmzeeman@xs4all.nl>
 2%% @copyright 2010 Maas-Maarten Zeeman
 3%% Date: 2010-12-03
 4%% @doc Signal and slot mechanism for use in templates.
 5
 6%% Copyright 2010 Maas-Maarten Zeeman
 7%%
 8%% Licensed under the Apache License, Version 2.0 (the "License");
 9%% you may not use this file except in compliance with the License.
10%% You may obtain a copy of the License at
11%% 
12%%     http://www.apache.org/licenses/LICENSE-2.0
13%% 
14%% Unless required by applicable law or agreed to in writing, software
15%% distributed under the License is distributed on an "AS IS" BASIS,
16%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17%% See the License for the specific language governing permissions and
18%% limitations under the License.
19
20-module(z_connect).
21-author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>").
22
23-export([page/3]).
24-export([slot/3]).
25
26-include("zotonic.hrl").
27
28% @doc Connect the signal to the page, when the signal is emitted, the
29% actions are rendered.
30% 
31page(Signal, Actions, Context) ->
32    AsyncContext = z_context:prune_for_async(Context),
33    z_context:spawn_link_page(?MODULE, slot, [Signal, Actions, AsyncContext], Context).
34
35%% @doc process which registers itself with the mod_signal module. It will receive a signal
36% if somebody emits a matching signal.
37%
38slot(SignalPrototype, Actions, ConnectorContext) ->
39    process_flag(trap_exit, true),
40    mod_signal:connect(SignalPrototype, self(), ConnectorContext),
41    receive_loop(SignalPrototype, Actions, ConnectorContext).
42
43% @doc Wait for incomging signals. When the signal arrives the actions are rendered, and send
44% to the page.
45%
46receive_loop(SignalPrototype, Actions, ConnectorContext) ->
47    receive 
48    {signal, Signal, _EmitterContext} ->
49        render_page_actions(Signal, Actions, ConnectorContext),
50        receive_loop(SignalPrototype, Actions, ConnectorContext);
51    {script, Script} ->
52        z_context:add_script_page(Script, ConnectorContext),
53        receive_loop(SignalPrototype, Actions, ConnectorContext);
54    disconnected ->
55        disconnected;
56    {'EXIT', _From, _Reason} ->
57        mod_signal:disconnect(SignalPrototype, self(), ConnectorContext)
58    end.
59
60% @doc Render the actions and send the scripts to the page connected to the signal.
61%
62render_page_actions(Signal, Actions, Context) ->
63    {_, SignalProps} = Signal,
64    Actions1 = [ {Name,  [ {signal, Signal}, {signal_props, SignalProps} | Props ] } || {Name, Props} <- Actions],
65    Options  = [{action, X} || X <- Actions1],
66
67    %% What parameters should be used here?
68    Script = z_script:get_script(z_render:wire(undefined, undefined, {event, Options}, Context)),
69    
70    z_context:add_script_page(Script, Context).