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