Skip to content
This repository
  • 8 commits
  • 17 files changed
  • 0 comments
  • 1 contributor
7 NEWS
... ... @@ -1,6 +1,13 @@
1 1 Welcome to Zotonic!
2 2
3 3
  4 +Release 0.7.1, released on 2011-08-03
  5 +-------------------------------------
  6 +
  7 +This is a bugfix release. See doc/changelogs/0.7.1.txt for all the
  8 +relevant bugfixes.
  9 +
  10 +
4 11 Release 0.7.0, released on 2011-07-28
5 12 -------------------------------------
6 13
4 doc/ZotonicCommands.txt
@@ -60,8 +60,8 @@ granted CREATEDB in postgres as follows:
60 60 zotonic debug
61 61 -------------
62 62 Launch the Zotonic server interactively and get an EShell on the
63   -running instance. This command used to be called "./start.sh" in
64   -Zotonic 0.6 and earlier.
  63 +running instance. There is a "start.sh" command in the root folder
  64 +which is a shortcut for this command.
65 65
66 66
67 67 zotonic restart
15 doc/changelogs/0.7.1.txt
... ... @@ -0,0 +1,15 @@
  1 +Zotonic 0.7.1
  2 +=============
  3 +
  4 +Released on 2011-08-03 13:17 by arjan.
  5 +
  6 +
  7 +Arjan
  8 +-----
  9 +
  10 + * Documentation fixes and fixed wrapping of homepage links in the www.zotonic.com site
  11 + * Fixed the menu editor: Added resource_menu_admin_menu again which was removed by accident.
  12 + * Reworked the way mod_logging notifies the log pages; it now uses mod_signal.
  13 + * Fixed quality=xx parameter to {% image %}.
  14 + * Added mod_signal to the default list of installed modules.
  15 +
4 doc/meta/DocumentationSnapshot.txt
... ... @@ -1,9 +1,9 @@
1   -cd /tmp
  1 +/cd /tmp
2 2 rm -rf zotonic-docs
3 3 mkdir zotonic-docs
4 4 cd zotonic-docs
5 5 httrack http://zotonic.com/
6 6 cd ..
7   -zip -r zotonic-html-documentation-20101003.zip zotonic-docs/
  7 +zip -r zotonic-html-documentation-`date +"%Y%m%d"`.zip zotonic-docs/
8 8
9 9 and upload to google code.
2  include/zotonic_release.hrl
@@ -17,4 +17,4 @@
17 17 %% limitations under the License.
18 18
19 19 %% Release number
20   --define(ZOTONIC_VERSION, "0.7.0").
  20 +-define(ZOTONIC_VERSION, "0.7.1").
41 modules/mod_logging/actions/action_logging_addlog.erl
... ... @@ -0,0 +1,41 @@
  1 +%% @author Arjan Scherpenisse <arjan@scherpenisse.net>
  2 +%% @copyright 2010 Arjan Scherpenisse <arjan@scherpenisse.net>
  3 +
  4 +%% Copyright 2010 Arjan Scherpenisse <arjan@scherpenisse.net>
  5 +%%
  6 +%% Licensed under the Apache License, Version 2.0 (the "License");
  7 +%% you may not use this file except in compliance with the License.
  8 +%% You may obtain a copy of the License at
  9 +%%
  10 +%% http://www.apache.org/licenses/LICENSE-2.0
  11 +%%
  12 +%% Unless required by applicable law or agreed to in writing, software
  13 +%% distributed under the License is distributed on an "AS IS" BASIS,
  14 +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15 +%% See the License for the specific language governing permissions and
  16 +%% limitations under the License.
  17 +
  18 +-module(action_logging_addlog).
  19 +-include("zotonic.hrl").
  20 +-export([
  21 + render_action/4
  22 +]).
  23 +
  24 +render_action(_TriggerId, TargetId, Args, Context) ->
  25 + SignalProps = proplists:get_value(signal_props, Args),
  26 + Type = proplists:get_value(type, SignalProps),
  27 +
  28 + {Tpl, Context1} = z_template:render_to_iolist(proplists:get_value(template, Args, "_admin_log_row.tpl"), Args, Context),
  29 + Tpl2 = lists:flatten(z_string:line(erlang:iolist_to_binary(Tpl))),
  30 + {[], z_script:add_script([
  31 + "$('", z_utils:js_escape(Tpl2),
  32 + "').hide().insertBefore('#", TargetId, " li:first').fadeIn().css({backgroundColor:'",
  33 + log_color(Type), "'}).animate({backgroundColor:'",
  34 + log_color(bg), "'}, 8000, 'linear');"], Context1)}.
  35 +
  36 +
  37 +log_color(debug) -> "#ffffff";
  38 +log_color(info) -> "#ffff99";
  39 +log_color(warning) -> "#ffcc99";
  40 +log_color(bg) -> "#f1f1f1";
  41 +log_color(_) -> "#f1f1f1".
51 modules/mod_logging/mod_logging.erl
@@ -29,9 +29,7 @@
29 29 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
30 30 -export([start_link/1]).
31 31 -export([
32   - add_admin_log_page/1,
33 32 observe_search_query/2,
34   - pid_observe_add_admin_log_page/3,
35 33 pid_observe_log/3
36 34 ]).
37 35
@@ -42,16 +40,9 @@
42 40
43 41 %% interface functions
44 42
45   -add_admin_log_page(C=#context{page_pid=Pid}) ->
46   - z_notifier:first({add_admin_log_page, Pid}, C).
47   -
48   -
49 43 observe_search_query({search_query, Req, OffsetLimit}, Context) ->
50 44 search(Req, OffsetLimit, Context).
51 45
52   -pid_observe_add_admin_log_page(Pid, {add_admin_log_page, _Pid} = Msg, _Context) ->
53   - gen_server:call(Pid, Msg).
54   -
55 46 pid_observe_log(Pid, {log, #log_message{}=Msg}, Context) ->
56 47 case Msg#log_message.user_id of
57 48 undefined -> gen_server:cast(Pid, {log, Msg#log_message{user_id=z_acl:user(Context)}});
@@ -93,9 +84,6 @@ init(Args) ->
93 84 %% {stop, Reason, Reply, State} |
94 85 %% {stop, Reason, State}
95 86 %% Description: Handling call messages
96   -handle_call({add_admin_log_page, Pid}, _From, State) ->
97   - Pids = lists:filter(fun erlang:is_process_alive/1, [Pid|State#state.admin_log_pages]),
98   - {reply, ok, State#state{admin_log_pages=Pids}};
99 87 handle_call(Message, _From, State) ->
100 88 {stop, {unknown_call, Message}, State}.
101 89
@@ -159,7 +147,6 @@ search(_, _, _) ->
159 147 undefined.
160 148
161 149
162   -
163 150 %% @doc Insert a simple log entry. Send an update to all UA's displaying the log.
164 151 handle_simple_log(#log_message{user_id=UserId, type=Type, message=Msg, props=Props}, State) ->
165 152 {ok, Id} = z_db:insert(log, [
@@ -167,33 +154,7 @@ handle_simple_log(#log_message{user_id=UserId, type=Type, message=Msg, props=Pro
167 154 {type, Type},
168 155 {message, Msg}
169 156 ] ++ Props, State#state.context),
170   -
171   - % Notify admins of any updates
172   - case State#state.admin_log_pages of
173   - [] ->
174   - nop;
175   - AdminPages ->
176   - case catch z_template:render_to_iolist("_admin_log_row.tpl", [{id, Id}], State#state.context) of
177   - {error, {template_not_found,"_admin_log_row.tpl",enoent}} ->
178   - % We can get a template_not_found error when the system is still starting.
179   - error;
180   - {error, Reason} ->
181   - error_logger:info_msg("[~p] Render error of _admin_log_row.tpl: ~p~n",
182   - [(State#state.context)#context.host, Reason]),
183   - error;
184   - {Tpl, _Ctx} ->
185   - Tpl2 = lists:flatten(z_string:line(erlang:iolist_to_binary(Tpl))),
186   - F = fun(Pid) ->
187   - z_session_page:add_script([
188   - "$('", z_utils:js_escape(Tpl2),
189   - "').hide().insertBefore('#log-area li:first').slideDown().css({backgroundColor:'",
190   - log_color(Type), "'}).animate({backgroundColor:'",
191   - log_color(bg), "'}, 8000, 'linear');"], Pid)
192   - end,
193   - [F(P) || P <- AdminPages],
194   - ok
195   - end
196   - end.
  157 + mod_signal:emit({log_message, [{log_id, Id}, {user_id, UserId}, {type, Type}, {message, Msg}, {props, Props}]}, State#state.context).
197 158
198 159
199 160 % All non #log_message{} logs are sent to their own log table. If the severity of the log entry is high enough then
@@ -209,7 +170,8 @@ handle_other_log(Record, State) ->
209 170 ?LOG_FATAL -> handle_simple_log(Log#log_message{type=fatal}, State);
210 171 ?LOG_ERROR -> handle_simple_log(Log#log_message{type=error}, State);
211 172 _Other -> nop
212   - end;
  173 + end,
  174 + mod_signal:emit({LogType, [{log_id, Id}|Fields]}, State#state.context);
213 175 false ->
214 176 Log = #log_message{
215 177 message=z_convert:to_binary(proplists:get_value(message, Fields, LogType)),
@@ -248,10 +210,3 @@ record_to_log_message(_, Fields, LogType, Id) ->
248 210
249 211 opt_user(undefined) -> [];
250 212 opt_user(Id) -> [" (", integer_to_list(Id), ")"].
251   -
252   -
253   -log_color(debug) -> "#ffffff";
254   -log_color(info) -> "#ffff99";
255   -log_color(warning) -> "#ffcc99";
256   -log_color(bg) -> "#f1f1f1";
257   -log_color(_) -> "#f1f1f1".
28 modules/mod_logging/scomps/scomp_logging_logwatch.erl
... ... @@ -1,28 +0,0 @@
1   -%% @author Arjan Scherpenisse <arjan@scherpenisse.net>
2   -%% @copyright 2010 Arjan Scherpenisse <arjan@scherpenisse.net>
3   -
4   -%% Copyright 2010 Arjan Scherpenisse <arjan@scherpenisse.net>
5   -%%
6   -%% Licensed under the Apache License, Version 2.0 (the "License");
7   -%% you may not use this file except in compliance with the License.
8   -%% You may obtain a copy of the License at
9   -%%
10   -%% http://www.apache.org/licenses/LICENSE-2.0
11   -%%
12   -%% Unless required by applicable law or agreed to in writing, software
13   -%% distributed under the License is distributed on an "AS IS" BASIS,
14   -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   -%% See the License for the specific language governing permissions and
16   -%% limitations under the License.
17   -
18   --module(scomp_logging_logwatch).
19   --behaviour(gen_scomp).
20   -
21   --export([vary/2, render/3]).
22   -
23   --include("zotonic.hrl").
24   -
25   -vary(_Params, _Context) -> nocache.
26   -render(_Params, _Vars, Context) ->
27   - mod_logging:add_admin_log_page(Context),
28   - {ok, []}.
2  modules/mod_logging/templates/_admin_log_row.tpl
... ... @@ -1,3 +1,4 @@
  1 +{% with signal_props.log_id|default:id as id %}
1 2 {% with m.log[id] as l %}
2 3 <li id="{{ #li.id }}" class="clearfix">
3 4 <span class="zp-5">{{ l.type|default:"-" }}</span>
@@ -21,3 +22,4 @@
21 22 <span class="zp-10">{{ l.created|date:"d M Y, H:i" }}</span>
22 23 </li>
23 24 {% endwith %}
  25 +{% endwith %}
3  modules/mod_logging/templates/admin_log.tpl
@@ -35,5 +35,6 @@
35 35 </div>
36 36 {% endwith %}
37 37
38   - {% logwatch %}
  38 + {% wire action={connect signal={log_message} action={addlog target="log-area"}} %}
  39 +
39 40 {% endblock %}
1  modules/mod_menu/mod_menu.erl
@@ -146,7 +146,6 @@ menu_flat(undefined, _Context) ->
146 146 menu_flat(<<>>, _Context) ->
147 147 [];
148 148 menu_flat(X, Context) ->
149   - ?DEBUG(X),
150 149 menu_flat(X, [1], [], Context).
151 150
152 151 menu_flat([], _Path, Acc, _Context) ->
128 modules/mod_menu/resources/resource_menu_admin_menu.erl
... ... @@ -0,0 +1,128 @@
  1 +%% @author Marc Worrell <marc@worrell.nl>
  2 +%% @copyright 2009 Marc Worrell
  3 +%% @doc Callbacks for editing the menu.
  4 +
  5 +%% Copyright 2009 Marc Worrell
  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 +
  19 +-module(resource_menu_admin_menu).
  20 +-author("Marc Worrell <marc@worrell.nl>").
  21 +
  22 +-export([
  23 + event/2,
  24 + test/0
  25 +]).
  26 +
  27 +-include("zotonic.hrl").
  28 +
  29 +event({drop, {dragdrop, ["new", Id], _, _DragEltId}, {dragdrop, [MenuId, "first"], _, _DropEltId}}, Context) ->
  30 + mod_menu:set_menu(MenuId, [{Id, []}], Context),
  31 + Html = z_template:render("_admin_menu_menu_view.tpl", [{id, MenuId}], Context),
  32 + z_render:update("menu-editor", Html, Context);
  33 +
  34 +event({drop, {dragdrop, DragTag, _, _DragEltId}, {dragdrop, [MenuId, "before", TP], _, _DropEltId}}, Context) ->
  35 + TargetPath = lists:reverse(TP),
  36 + Menu = mod_menu:get_menu(MenuId, Context),
  37 + Menu2 = case DragTag of
  38 + ["new", NewId] ->
  39 + insert_menuitem(Menu, {NewId, []}, TargetPath);
  40 + Path ->
  41 + SourcePath = lists:reverse(Path),
  42 + MenuItem = get_menuitem(Menu, SourcePath),
  43 + Menu1 = delete_path(Menu, SourcePath),
  44 + TargetPath1 = path_after_delete(TargetPath, SourcePath),
  45 + insert_menuitem(Menu1, MenuItem, TargetPath1)
  46 + end,
  47 + mod_menu:set_menu(MenuId, Menu2, Context),
  48 + Html = z_template:render("_admin_menu_menu_view.tpl", [{id, MenuId}], Context),
  49 + z_render:update("menu-editor", Html, Context);
  50 +
  51 +event({drop, {dragdrop, DragTag, _, _DragEltId}, {dragdrop, [MenuId, "on", TargetPath], _, _DropEltId}}, Context) ->
  52 + event({drop, {dragdrop, DragTag, x, x}, {dragdrop, [MenuId, "before", [1|TargetPath]], x, x}}, Context);
  53 +
  54 +event({postback, {delete, Props}, _TriggerId, _TargetId}, Context) ->
  55 + MenuId = proplists:get_value(menu_id, Props),
  56 + Path = lists:reverse(proplists:get_value(path, Props)),
  57 + Menu = mod_menu:get_menu(MenuId, Context),
  58 + Menu1 = delete_path(Menu, Path),
  59 + mod_menu:set_menu(MenuId, Menu1, Context),
  60 + Html = z_template:render("_admin_menu_menu_view.tpl", [{id, MenuId}], Context),
  61 + z_render:update("menu-editor", Html, Context);
  62 +
  63 +event(_Event, Context) ->
  64 + Context.
  65 +
  66 +
  67 +delete_path(Menu, Path) ->
  68 + delete_path(Menu, Path, []).
  69 +delete_path([_|Rest], [1], Acc) ->
  70 + lists:reverse(Acc) ++ Rest;
  71 +delete_path([Item|Rest], [Idx], Acc) ->
  72 + delete_path(Rest, [Idx-1], [Item|Acc]);
  73 +delete_path([{Id,SubMenu}|Rest], [1|Path], Acc) ->
  74 + lists:reverse(Acc)
  75 + ++ [{Id, delete_path(SubMenu, Path)} | Rest];
  76 +delete_path([Item|Menu], [Idx|Path], Acc) ->
  77 + delete_path(Menu, [Idx-1|Path], [Item|Acc]).
  78 +
  79 +
  80 +get_menuitem([Item|_Menu], [1]) ->
  81 + Item;
  82 +get_menuitem([_Item|Menu], [Idx]) ->
  83 + get_menuitem(Menu, [Idx-1]);
  84 +get_menuitem([{_, SubMenu}|_Rest], [1|PathRest]) ->
  85 + get_menuitem(SubMenu, PathRest);
  86 +get_menuitem([_|Rest], [Idx|PathRest]) ->
  87 + get_menuitem(Rest, [Idx-1|PathRest]).
  88 +
  89 +
  90 +insert_menuitem(Menu, Item, DestPath) ->
  91 + insert_menuitem(Menu, Item, DestPath, []).
  92 +insert_menuitem(Menu, Item, [1], Acc) ->
  93 + lists:reverse(Acc) ++ [Item | Menu];
  94 +insert_menuitem([First|Rest], Item, [Idx], Acc) ->
  95 + insert_menuitem(Rest, Item, [Idx-1], [First|Acc]);
  96 +insert_menuitem([{Id, SubMenu} | MenuRest], Item, [1|Path], Acc) ->
  97 + lists:reverse(Acc)
  98 + ++ [{Id, insert_menuitem(SubMenu, Item, Path, [])} | MenuRest];
  99 +insert_menuitem([MenuItem|MenuRest], Item, [Idx|Path], Acc) ->
  100 + insert_menuitem(MenuRest, Item, [Idx-1|Path], [MenuItem|Acc]).
  101 +
  102 +
  103 +path_after_delete(Path, DeletePath) ->
  104 + path_after_delete(Path, DeletePath, []).
  105 +path_after_delete([], _, Acc) ->
  106 + lists:reverse(Acc);
  107 +path_after_delete(Path, [], Acc) ->
  108 + lists:reverse(Acc) ++ Path;
  109 +path_after_delete([X|Rest], [Y|Rest2], Acc) when X > Y ->
  110 + path_after_delete(Rest, Rest2, [X-1|Acc]);
  111 +path_after_delete([X|Rest], [_|Rest2], Acc) ->
  112 + path_after_delete(Rest, Rest2, [X|Acc]).
  113 +
  114 +
  115 +test() ->
  116 + [foo] = insert_menuitem([], foo, [1]),
  117 + [foo, bar] = insert_menuitem([bar], foo, [1]),
  118 + [bar, foo, baz] = insert_menuitem([bar, baz], foo, [2]),
  119 + [bar, baz, foo] = insert_menuitem([bar, baz], foo, [3]),
  120 + [{x, [foo]}, {y, []}] = insert_menuitem([{x, []}, {y, []}], foo, [1, 1]),
  121 + [{x, []}, {y, [foo]}] = insert_menuitem([{x, []}, {y, []}], foo, [2, 1]),
  122 + [{x, []}, {y, [{z, [bleh, foo]}]}] = insert_menuitem([{x, []}, {y, [{z, [bleh]}]}], foo, [2, 1, 2]),
  123 +
  124 + [b] = delete_path([a, b], [1]),
  125 + [a] = delete_path([a, b], [2]),
  126 +
  127 + [a, {b, []}, c] = delete_path([a, {b, [x]}, c], [2, 1]),
  128 + [a, {b, [x]}, c] = delete_path([a, {b, [x,y]}, c], [2, 2]).
5 modules/mod_signal/z_connect.erl
@@ -57,9 +57,10 @@ receive_loop(SignalPrototype, Actions, ConnectorContext) ->
57 57 % @doc Render the actions and send the scripts to the page connected to the signal.
58 58 %
59 59 render_page_actions(Signal, Actions, Context) ->
60   - Actions1 = [ {Name, [ {signal, Signal} | Props ] } || {Name, Props} <- Actions],
  60 + {_, SignalProps} = Signal,
  61 + Actions1 = [ {Name, [ {signal, Signal}, {signal_props, SignalProps} | Props ] } || {Name, Props} <- Actions],
61 62 Options = [{action, X} || X <- Actions1],
62   -
  63 +
63 64 %% What parameters should be used here?
64 65 Script = z_script:get_script(z_render:wire(undefined, undefined, {event, Options}, Context)),
65 66
6 priv/sites/zotonicwww/lib/css/zp-project.css
@@ -230,14 +230,16 @@ header {
230 230
231 231 .home #banner #download-zotonic {
232 232 position: absolute;
233   - right: 63px;
  233 + left: 625px;
234 234 top: 40px;
  235 + width: 350px;
235 236 }
236 237
237 238 .home #banner #docs-zotonic {
238 239 position: absolute;
239   - right: 9px;
  240 + left: 625px;
240 241 top: 170px;
  242 + width: 350px;
241 243 }
242 244
243 245 .home #banner #download-zotonic a,
10 src/install/z_install_data.erl
@@ -57,31 +57,27 @@ install_modules(Host, C) ->
57 57 ?DEBUG("Inserting modules"),
58 58 Modules = [
59 59 "mod_base",
60   - "mod_emailer",
61 60 "mod_menu",
62 61 "mod_oauth",
63 62 "mod_search",
64 63 "mod_video_embed",
65 64 "mod_atom_feed",
66   - "mod_broadcast",
67 65 "mod_translation",
68   - "mod_log",
  66 + "mod_signal",
  67 + "mod_logging",
69 68
70 69 "mod_seo",
71 70 "mod_seo_google",
72 71 "mod_seo_sitemap",
73 72
74 73 "mod_authentication",
75   - "mod_acl_adminonly",
  74 + "mod_acl_adminonly",
76 75
77 76 "mod_admin",
78   - "mod_admin_address",
79 77 "mod_admin_category",
80 78 "mod_admin_config",
81   - "mod_admin_event",
82 79 "mod_admin_identity",
83 80 "mod_admin_modules",
84   - "mod_admin_person",
85 81 "mod_admin_predicate",
86 82
87 83 %% Enable comments
17 src/support/z_media_preview.erl
@@ -36,9 +36,6 @@
36 36 -define(MAX_WIDTH, 5000).
37 37 -define(MAX_HEIGHT, 5000).
38 38
39   --define(PIX100, 1000).
40   --define(PIX50, 250000).
41   -
42 39 -include_lib("zotonic.hrl").
43 40
44 41
@@ -147,14 +144,10 @@ cmd_args(FileProps, Filters, OutMime) ->
147 144 {resize, ResizeWidth, ResizeHeight, is_enabled(upscale, Filters)},
148 145 {crop, CropArgs},
149 146 {colorspace, "RGB"} | Filters1],
150   - Filters2b = case {CropArgs,is_enabled(extent, Filters)} of
  147 + Filters3 = case {CropArgs,is_enabled(extent, Filters)} of
151 148 {none,true} -> Filters2 ++ [{extent, ReqWidth, ReqHeight}];
152 149 _ -> Filters2
153 150 end,
154   - Filters3 = case OutMime of
155   - "image/jpg" -> Filters2b ++ [quality];
156   - _ -> Filters2b
157   - end,
158 151 Filters4 = case is_blurred(Filters3) of
159 152 true -> Filters3;
160 153 false -> case Mime of
@@ -293,13 +286,7 @@ filter2arg(sharpen_small, Width, Height) ->
293 286 {Width, Height, []};
294 287 filter2arg(lossless, Width, Height) ->
295 288 {Width, Height, []};
296   -filter2arg(quality, Width, Height) ->
297   - Pix = Width * Height,
298   - Q = if
299   - Pix < ?PIX100 -> 100;
300   - Pix > ?PIX50 -> 50;
301   - true -> 100 - round(50 * (Pix - ?PIX100) / (?PIX50 - ?PIX100))
302   - end,
  289 +filter2arg({quality, Q}, Width, Height) ->
303 290 {Width,Height, ["-quality ",integer_to_list(Q)]};
304 291 filter2arg({removebg, Fuzz}, Width, Height) ->
305 292 {Width, Height, ["-matte -fill none -fuzz ", integer_to_list(Fuzz), "% ",
2  src/zotonic.app
... ... @@ -1,6 +1,6 @@
1 1 {application, zotonic,
2 2 [{description, "zotonic"},
3   - {vsn, "0.7.0"},
  3 + {vsn, "0.7.1"},
4 4 {modules, [
5 5 zotonic,
6 6 zotonic_app,

No commit comments for this range

Something went wrong with that request. Please try again.