Permalink
Browse files

mod_survey now uses blocks instead of its own 'survey' data structure…

…. Added pluggable blocks to the mod_admin. Added z_html:escape/2 for easy z_trans selection in combination with escape. Fixed issue in z_validation when the name was a binary.
  • Loading branch information...
1 parent 450f2ac commit 52072ebe84122f674a8cd1b35a871243a826f6ad @mworrell mworrell committed Jul 11, 2012
Showing with 1,565 additions and 1,693 deletions.
  1. +6 −0 include/zotonic_notifications.hrl
  2. +1 −1 modules/mod_admin/lib/css/bootstrap-admin.css
  3. +8 −0 modules/mod_admin/lib/css/zotonic-admin.css
  4. +13 −1 modules/mod_admin/mod_admin.erl
  5. +4 −1 modules/mod_admin/resources/resource_admin_edit.erl
  6. +9 −4 modules/mod_admin/templates/_admin_edit_block_addblock.tpl
  7. +9 −7 modules/mod_admin/templates/_admin_edit_block_li.tpl
  8. +3 −0 modules/mod_admin/templates/admin_edit_widget_i18n.tpl
  9. +2 −0 modules/mod_admin/templates/admin_edit_widget_std.tpl
  10. 0 modules/mod_admin/templates/{ → blocks}/_admin_edit_block_li_header.tpl
  11. 0 modules/mod_admin/templates/{ → blocks}/_admin_edit_block_li_text.tpl
  12. +14 −5 modules/mod_base/filters/filter_replace.erl
  13. +1 −5 modules/mod_base_site/templates/text/_blocks.tpl
  14. +1 −0 modules/mod_base_site/templates/text/blocks/_block_view_header.tpl
  15. +1 −0 modules/mod_base_site/templates/text/blocks/_block_view_text.tpl
  16. +0 −79 modules/mod_survey/actions/action_survey_dialog_survey_question.erl
  17. +0 −59 modules/mod_survey/actions/action_survey_dialog_survey_question_delete.erl
  18. +55 −0 modules/mod_survey/filters/filter_survey_prepare_matching.erl
  19. +93 −0 modules/mod_survey/filters/filter_survey_prepare_narrative.erl
  20. +44 −0 modules/mod_survey/filters/filter_survey_prepare_thurstone.erl
  21. +153 −208 modules/mod_survey/mod_survey.erl
  22. +67 −52 modules/mod_survey/models/m_survey.erl
  23. +22 −55 modules/mod_survey/questions/survey_q_likert.erl
  24. +58 −0 modules/mod_survey/questions/survey_q_long_answer.erl
  25. +0 −85 modules/mod_survey/questions/survey_q_longanswer.erl
  26. +39 −102 modules/mod_survey/questions/survey_q_matching.erl
  27. +46 −140 modules/mod_survey/questions/survey_q_narrative.erl
  28. +82 −0 modules/mod_survey/questions/survey_q_page_break.erl
  29. +0 −106 modules/mod_survey/questions/survey_q_pagebreak.erl
  30. +0 −70 modules/mod_survey/questions/survey_q_prompt.erl
  31. +60 −0 modules/mod_survey/questions/survey_q_short_answer.erl
  32. +0 −86 modules/mod_survey/questions/survey_q_shortanswer.erl
  33. +0 −70 modules/mod_survey/questions/survey_q_subhead.erl
  34. +0 −68 modules/mod_survey/questions/survey_q_textblock.erl
  35. +34 −78 modules/mod_survey/questions/survey_q_thurstone.erl
  36. +26 −55 modules/mod_survey/questions/survey_q_truefalse.erl
  37. +30 −55 modules/mod_survey/questions/survey_q_yesno.erl
  38. +70 −1 modules/mod_survey/support/mod_survey_schema.erl
  39. +1 −3 modules/mod_survey/survey.hrl
  40. +0 −50 modules/mod_survey/templates/_action_dialog_survey_question.tpl
  41. +0 −7 modules/mod_survey/templates/_action_dialog_survey_question_delete.tpl
  42. +3 −24 modules/mod_survey/templates/_admin_edit_content.survey.tpl
  43. +0 −14 modules/mod_survey/templates/_survey_question_likert.tpl
  44. +0 −5 modules/mod_survey/templates/_survey_question_longanswer.tpl
  45. +0 −29 modules/mod_survey/templates/_survey_question_matching.tpl
  46. +0 −21 modules/mod_survey/templates/_survey_question_narrative.tpl
  47. +17 −49 modules/mod_survey/templates/_survey_question_page.tpl
  48. +0 −1 modules/mod_survey/templates/_survey_question_prompt.tpl
  49. +0 −16 modules/mod_survey/templates/_survey_question_shortanswer.tpl
  50. +0 −1 modules/mod_survey/templates/_survey_question_subhead.tpl
  51. +0 −1 modules/mod_survey/templates/_survey_question_textblock.tpl
  52. +0 −15 modules/mod_survey/templates/_survey_question_thurstone.tpl
  53. +0 −8 modules/mod_survey/templates/_survey_question_truefalse.tpl
  54. +0 −8 modules/mod_survey/templates/_survey_question_yesno.tpl
  55. +8 −17 modules/mod_survey/templates/_survey_start.tpl
  56. +56 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_likert.tpl
  57. +32 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_long_answer.tpl
  58. +42 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_matching.tpl
  59. +34 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_narrative.tpl
  60. +45 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_page_break.tpl
  61. +41 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_short_answer.tpl
  62. +43 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_thurstone.tpl
  63. +46 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_truefalse.tpl
  64. +45 −0 modules/mod_survey/templates/blocks/_admin_edit_block_li_survey_yesno.tpl
  65. +20 −0 modules/mod_survey/templates/blocks/_block_view_survey_likert.tpl
  66. +10 −0 modules/mod_survey/templates/blocks/_block_view_survey_long_answer.tpl
  67. +25 −0 modules/mod_survey/templates/blocks/_block_view_survey_matching.tpl
  68. +23 −0 modules/mod_survey/templates/blocks/_block_view_survey_narrative.tpl
  69. +1 −0 modules/mod_survey/templates/blocks/_block_view_survey_page_break.tpl
  70. +21 −0 modules/mod_survey/templates/blocks/_block_view_survey_short_answer.tpl
  71. +34 −0 modules/mod_survey/templates/blocks/_block_view_survey_thurstone.tpl
  72. +14 −0 modules/mod_survey/templates/blocks/_block_view_survey_truefalse.tpl
  73. +15 −0 modules/mod_survey/templates/blocks/_block_view_survey_yesno.tpl
  74. +11 −13 modules/mod_survey/templates/survey.tpl
  75. +2 −1 modules/mod_survey/templates/survey_results.tpl
  76. +23 −16 src/support/z_html.erl
  77. +2 −1 src/support/z_validation.erl
@@ -103,6 +103,11 @@
%% @doc Rewrite an url before it will be dispatched using the z_dispatcher (foldl)
-record(dispatch_rewrite, {is_dir=false, path=""}).
+%% @doc Used in the admin to fetch the possible blocks for display (foldl)
+-record(admin_edit_blocks, {id}).
+
+%% Used for fetching the menu in the admin (foldl)
+% admin_menu
%% @doc 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 interested
@@ -224,6 +229,7 @@
%% @doc Check if an action is allowed (first).
%% Should return undefined, true or false.
+%% action :: view|update|delete
-record(acl_is_allowed, {action, object}).
%% @doc Check if an action on a property is allowed (first).

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -364,6 +364,14 @@ ul.blocks .ui-sortable-placeholder {
visibility: visible !important;
}
+.input.inline {
+ display:inline-block;
+ padding-top:5px;
+ margin-bottom:0;
+ vertical-align:sub;
+}
+
+
/* Connections
---------------------------------------------------------- */
ul.connections-list {
@@ -29,6 +29,7 @@
-export([
observe_sanitize_element/3,
observe_admin_menu/3,
+ observe_admin_edit_blocks/3,
event/2
]).
@@ -122,6 +123,16 @@ observe_admin_menu(admin_menu, Acc, Context) ->
|Acc].
+observe_admin_edit_blocks(#admin_edit_blocks{}, Menu, Context) ->
+ [
+ {1, ?__("Texts", Context), [
+ {header, ?__("Header", Context)},
+ {text, ?__("Text", Context)}
+ ]}
+ | Menu
+ ].
+
+
event(#postback_notify{message="admin-insert-block"}, Context) ->
Language = case z_context:get_q("language", Context) of
undefined ->
@@ -149,7 +160,8 @@ event(#postback_notify{message="admin-insert-block"}, Context) ->
{edit_language, EditLanguage},
is_new,
{is_editable, z_acl:rsc_editable(RscId, Context)},
- {blk, [{type, Type}]}
+ {blk, [{type, Type}]},
+ {blocks, lists:sort(z_notifier:foldl(#admin_edit_blocks{id=RscId}, [], Context))}
]
},
case z_html:escape(z_context:get_q("after", Context)) of
@@ -44,8 +44,11 @@ resource_exists(ReqData, Context) ->
html(Context) ->
+ Id = z_context:get(id, Context),
+ Blocks = z_notifier:foldl(#admin_edit_blocks{id=Id}, [], Context),
Vars = [
- {id, z_context:get(id, Context)}
+ {id, Id},
+ {blocks, lists:sort(Blocks)}
],
Html = z_template:render({cat, "admin_edit.tpl"}, Vars, Context),
z_context:output(Html, Context).
@@ -4,10 +4,15 @@
{_ + add block _}
<span class="caret"></span>
</a>
- <ul class="dropdown-menu">
- <li><a href="#" data-block-type="header">{_ Header _}</li></a>
- <li><a href="#" data-block-type="text">{_ Text _}</li></a>
- {# <li><a href="#" data-block-type="media">{_ Media _}</li></a> #}
+ <ul class="dropdown-menu nav-list nav">
+ {% for _order, title, items in blocks %}
+ {% if title %}
+ <li class="nav-header">{{ title }}</li>
+ {% endif %}
+ {% for type, title in items %}
+ <li><a href="#" data-block-type="{{ type }}">{{ title }}</li></a>
+ {% endfor %}
+ {% endfor %}
</ul>
</div>
{% endif %}
@@ -3,16 +3,12 @@
<h3 class="widget-header">
<i title="{_ Drag to change position _}" class="icon-move"></i>
<span title="{_ Disconnect _}" class="icon-remove"></span>
- <span>{{ blk.type|make_list|capfirst }} {_ block _}</span>
- <input type="text" class="block-name" name="block-{{#s}}-name" id="block-{{#s}}-name" value="{{ blk.name|escape }}" title="{_ Block name _}" />
+ <span>{{ blk.type|make_list|capfirst|replace:"_":" " }} {_ block _}</span>
+ <input type="text" class="block-name" name="block-{{#s}}-name" id="block-{{#s}}-name" value="{{ blk.name|escape }}" title="{_ Block name _}" placeholder="{_ name _}" />
</h3>
<div class="widget-content">
<input type="hidden" name="block-{{#s}}-type" value="{{ blk.type }}" />
- {% if blk.type == 'text' or not blk %}
- {% include "_admin_edit_block_li_text.tpl" name=#s %}
- {% elseif blk.type == 'header' %}
- {% include "_admin_edit_block_li_header.tpl" name=#s %}
- {% endif %}
+ {% include ["blocks/_admin_edit_block_li_",blk.type,".tpl"]|join name=#s blk=blk id=id is_editable=is_editable is_new=is_new %}
</div>
{% if is_new %}
{% javascript %}
@@ -23,3 +19,9 @@
{% include "_admin_edit_block_addblock.tpl" %}
</li>
{% endwith %}
+
+{% if is_new %}
+{% javascript %}
+ $("#{{ #block }} .widget").effect("highlight");
+{% endjavascript %}
+{% endif %}
@@ -19,6 +19,9 @@
{% endwith %}
{% endfor %}
</div>
+ <div class="tab-content widget-content">
+ {% block widget_content_nolang %}{% endblock %}
+ </div>
</div>
{% block widget_after %}{% endblock %}
@@ -3,11 +3,13 @@
{% block widget_before %}{% endblock %}
<div id="{% block widget_id %}{% endblock %}" class="{% if in_dialog %}dialog-{% endif %}widget {% block widget_class %}{% endblock %} do_adminwidget" data-adminwidget="minifiedOnInit: {% block widget_show_minimized %}false{% endblock %}">
+ {% block widget_header %}
{% if not in_dialog %}
<h3 class="widget-header">
{% block widget_title %}{% endblock %}
</h3>
{% endif %}
+ {% endblock %}
<div class="widget-content">
{% block widget_content %}{% endblock %}
</div>
@@ -17,12 +17,21 @@
%% limitations under the License.
-module(filter_replace).
--export([replace/3]).
+-export([
+ replace/3,
+ replace/4
+]).
replace(undefined, _, _Context) ->
undefined;
-replace(In, [A,B], _Context) when is_binary(A) orelse is_list(A) ->
- iolist_to_binary(re:replace(In, A, B, [global]));
-replace(In, A, _Context) ->
- iolist_to_binary(re:replace(In, A, [], [global])).
+replace(In, [A,B], Context) when is_binary(A) orelse is_list(A) ->
+ replace(In, A, B, Context);
+replace(In, A, Context) ->
+ replace(In, A, <<>>, Context).
+
+replace(In, A, B, Context) ->
+ In1 = z_trans:lookup_fallback(In, Context),
+ A1 = z_trans:lookup_fallback(A, Context),
+ B1 = z_trans:lookup_fallback(B, Context),
+ iolist_to_binary(re:replace(In1, A1, B1, [global])).
@@ -1,7 +1,3 @@
{% for blk in m.rsc[id].blocks %}
- {% if blk.type == 'header' %}
- <h2 class="block-header" {% if blk.name %}id="{{ blk.name }}"{% endif %}>{{ blk.header }}</h2>
- {% elseif blk.body %}
- <div class="block-text">{{ blk.body|show_media }}</div>
- {% endif %}
+ {% include ["blocks/_block_view_",blk.type,".tpl"]|join blk=blk id=id %}
{% endfor %}
@@ -0,0 +1 @@
+<h2 class="block-header" {% if blk.name %}id="{{ blk.name }}"{% endif %}>{{ blk.header }}</h2>
@@ -0,0 +1 @@
+<div class="block-text">{{ blk.body|show_media }}</div>
@@ -1,79 +0,0 @@
-%% @author Marc Worrell <marc@worrell.nl>
-%% @copyright 2010-2011 Marc Worrell
-%% @doc Open a dialog to edit a survey question.
-
-%% Copyright 2010-2011 Marc Worrell
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-
--module(action_survey_dialog_survey_question).
--author("Marc Worrell <marc@worrell.nl").
-
-%% interface functions
--export([
- render_action/4,
- event/2
-]).
-
--include("zotonic.hrl").
--include("../survey.hrl").
-
-render_action(TriggerId, TargetId, Args, Context) ->
- Id = z_convert:to_integer(proplists:get_value(id, Args)),
- QuestionId = proplists:get_value(question_id, Args),
- Postback = {dialog_survey_question, Id, QuestionId},
- {PostbackMsgJS, _PickledPostback} = z_render:make_postback(Postback, click, TriggerId, TargetId, ?MODULE, Context),
- {PostbackMsgJS, Context}.
-
-
-%% @doc Fill the dialog with the duplicate page form. The form will be posted back to this module.
-%% @spec event(Event, Context1) -> Context2
-event(#postback{message={dialog_survey_question, Id, QuestionId}}, Context) ->
- Q = get_question(Id, QuestionId, Context),
- Vars = [
- {id, Id},
- {question_id, QuestionId},
- {delegate, atom_to_list(?MODULE)}
- ] ++ question_props(Q),
- z_render:dialog("Edit survey question.", "_action_dialog_survey_question.tpl", Vars, Context);
-
-event(#submit{message={survey_question_save, ActionProps}}, Context) ->
- Id = proplists:get_value(id, ActionProps),
- QuestionId = proplists:get_value(question_id, ActionProps),
- Name = z_string:truncate(z_string:to_name(z_string:trim(z_context:get_q("name", Context, ""))), 32, []),
- Question = z_string:trim(z_context:get_q("question", Context, "")),
- Text = z_string:trim(z_context:get_q("text", Context, "")),
- IsRequired = z_convert:to_bool(z_context:get_q("is_required", Context, "")),
- Q = get_question(Id, QuestionId, Context),
- Q1 = question_render(Q#survey_question{name=Name, question=Question, text=Text, is_required=IsRequired}),
- save_question(Id, QuestionId, Q1, Context),
- Context1 = mod_survey:redraw_questions(Id, Context),
- z_render:dialog_close(Context1).
-
-
-get_question(Id, QuestionId, Context) ->
- {survey, _QIds, Qs} = m_rsc:p(Id, survey, Context),
- proplists:get_value(QuestionId, Qs).
-
-save_question(Id, QuestionId, Question, Context) ->
- {survey, QIds, Qs} = m_rsc:p(Id, survey, Context),
- m_rsc:update(Id, [{survey, {survey, QIds, z_utils:prop_replace(QuestionId, Question, Qs)}}], Context).
-
-
-question_props(Q) ->
- Mod = mod_survey:module_name(Q),
- Mod:question_props(Q).
-
-question_render(Q) ->
- Mod = list_to_atom("survey_q_"++z_convert:to_list(Q#survey_question.type)),
- Mod:render(Q).
@@ -1,59 +0,0 @@
-%% @author Marc Worrell <marc@worrell.nl>
-%% @copyright 2010-2011 Marc Worrell
-%% @doc Delete a question from a survey, request confirmation.
-
-%% Copyright 2010-2011 Marc Worrell
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-
--module(action_survey_dialog_survey_question_delete).
--author("Marc Worrell <marc@worrell.nl").
-
-%% interface functions
--export([
- render_action/4,
- event/2
-]).
-
--include("zotonic.hrl").
-
-render_action(TriggerId, TargetId, Args, Context) ->
- Id = z_convert:to_integer(proplists:get_value(id, Args)),
- QuestionId = proplists:get_value(question_id, Args),
- Postback = {survey_delete_question_dialog, Id, QuestionId},
- {PostbackMsgJS, _PickledPostback} = z_render:make_postback(Postback, click, TriggerId, TargetId, ?MODULE, Context),
- {PostbackMsgJS, Context}.
-
-
-%% @doc Fill the dialog with the delete confirmation template. The next step will ask to delete the resource
-%% @spec event(Event, Context1) -> Context2
-event(#postback{message={survey_delete_question_dialog, Id, QuestionId}}, Context) ->
- case z_acl:rsc_editable(Id, Context) of
- true ->
- Vars = [
- {id, Id},
- {question_id, QuestionId},
- {delegate, ?MODULE}
- ],
- z_render:dialog("Confirm delete", "_action_dialog_survey_question_delete.tpl", Vars, Context);
- false ->
- z_render:growl_error("You are not allowed to edit this page.", Context)
- end;
-
-event(#postback{message={survey_delete_question, Props}}, Context) ->
- Id = proplists:get_value(id, Props),
- QuestionId = proplists:get_value(question_id, Props),
- mod_survey:delete_question(Id, QuestionId, Context).
-
-
-
Oops, something went wrong.

0 comments on commit 52072eb

Please sign in to comment.