Compare commits

..

10 Commits

Author SHA1 Message Date
jocelyn ad4f020d0e The NULL storage may look into the CMS configuration file.
This allows to run the CMS without any database.
2015-08-21 19:16:31 +02:00
jocelyn 7a13b47131 Fixed cms library compilation.
CMS_FILE_BLOCK was missing `is_empty' implementation.
2015-08-19 12:34:35 +02:00
jocelyn 923089baa1 Better js code to apply CKEditor.replace, mainly to select only textarea.name=$name.
code cleaning.
2015-08-18 19:24:18 +02:00
jocelyn cfec9dc7f8 Do not include empty blocks, this way, we avoid empty sidebars if not needed. 2015-08-18 10:58:31 +02:00
jocelyn b5e7d5d201 Require "view recent changes" permission to see the recent changes. 2015-08-17 17:40:55 +02:00
jocelyn e1bdcb965c Added permission arguments to "trash" and "Create" links.
Added blocks configuration settings via the cms.ini and "blocks" section
   ex: [blocks]
       navigation.region=sidebar_first
   This enables the site to change default block location, and even hides it easily, if the theme does not include associated region name.
2015-08-13 00:44:16 +02:00
jocelyn 0061afcbe8 use "deleted" instead of "trashed" . 2015-08-12 19:03:40 +02:00
jocelyn 6a9bc8aa42 Updated admin and recent_changes module permissions declaration. 2015-08-12 19:00:17 +02:00
jocelyn 1d7d79d69e Cleaned up hooks related code, and always go via CMS_RESPONSE.hooks 2015-08-12 17:50:23 +02:00
jocelyn 46014da3d8 Added recent_changes module.
Revisited hooks management, and added new CMS_HOOK_MANAGER.
Added admin, and other link into navigation menu that goes into first sidebar.
Fixed theme info, and template for sidebar ids.
Better css class name for cms node content.
2015-08-12 17:30:07 +02:00
28 changed files with 415 additions and 292 deletions
+3
View File
@@ -31,6 +31,9 @@ node=on
oauth20=on
openid=on
[blocks]
#navigation.region=sidebar_first
[admin]
# CMS Installation, are accessible by "all", "none" or uppon "permission". (default is none)
installation_access=permission
+1
View File
@@ -90,6 +90,7 @@ feature -- Security
Result.force ("admin users")
Result.force ("admin roles")
Result.force ("admin modules")
Result.force ("install modules")
end
feature -- Hooks
@@ -84,7 +84,7 @@ feature -- Process Edit
do
create b.make_empty
f := new_edit_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.validation_actions.extend (agent edit_form_validate(?,a_role, b))
f.submit_actions.extend (agent edit_form_submit(?, a_role, b))
@@ -117,7 +117,7 @@ feature -- Process Delete
do
create b.make_empty
f := new_delete_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.process (Current)
fd := f.last_data
@@ -149,7 +149,7 @@ feature -- Process New
do
create b.make_empty
f := new_edit_form (l_role, url (request.percent_encoded_path_info, Void), "create-role")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.validation_actions.extend (agent new_form_validate(?, b))
f.submit_actions.extend (agent edit_form_submit(?, l_role, b))
@@ -86,7 +86,7 @@ feature -- Process Edit
do
create b.make_empty
f := new_edit_form (a_user, url (location, Void), "edit-user")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.submit_actions.extend (agent edit_form_submit (?, a_user, b))
f.process (Current)
@@ -118,7 +118,7 @@ feature -- Process Delete
do
create b.make_empty
f := new_delete_form (a_user, url (location, Void), "edit-user")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.process (Current)
fd := f.last_data
@@ -151,7 +151,7 @@ feature -- Process New
do
create b.make_empty
f := new_edit_form (l_user, url (location, Void), "create-user")
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.validation_actions.extend (agent new_form_validate (?, b))
f.submit_actions.extend (agent edit_form_submit (?, l_user, b))
+7 -1
View File
@@ -236,11 +236,17 @@ feature -- Access: Node
end
recent_nodes (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_NODE]
-- List of the `a_rows' most recent nodes starting from `a_offset'.
-- List of most recent nodes according to `params.offset' and `params.size'.
do
Result := node_storage.recent_nodes (params.offset.to_integer_32, params.size.to_integer_32)
end
recent_node_changes_before (params: CMS_DATA_QUERY_PARAMETERS; a_date: DATE_TIME): ITERABLE [CMS_NODE]
-- List of recent changes, before `a_date', according to `params' settings.
do
Result := node_storage.recent_node_changes_before (params.offset.to_integer_32, params.size.to_integer_32, a_date)
end
node (a_id: INTEGER_64): detachable CMS_NODE
-- Node by ID.
do
+40 -16
View File
@@ -173,6 +173,7 @@ feature -- Access
Result.force ("view revisions own " + l_type_name)
end
end
Result.force ("view trash")
end
end
@@ -255,6 +256,7 @@ feature -- Hooks
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
perms: ARRAYED_LIST [READABLE_STRING_8]
do
debug
create lnk.make ("List of nodes", "nodes")
@@ -262,9 +264,20 @@ feature -- Hooks
end
create lnk.make ("Trash", "trash")
a_menu_system.navigation_menu.extend (lnk)
lnk.set_permission_arguments (<<"view trash">>)
create lnk.make ("Create ..", "node")
a_menu_system.navigation_menu.extend (lnk)
if attached node_api as l_node_api then
create perms.make (2)
perms.force ("create any node")
across
l_node_api.content_types as ic
loop
perms.force ("create " + ic.item.name)
end
lnk.set_permission_arguments (perms)
end
end
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8])
@@ -273,6 +286,8 @@ feature -- Hooks
ch: CMS_RECENT_CHANGE_ITEM
n: CMS_NODE
l_info: STRING_8
l_src: detachable READABLE_STRING_8
l_nodes: ITERABLE [CMS_NODE]
do
create params.make (0, a_changes.limit)
if attached node_api as l_node_api then
@@ -281,27 +296,36 @@ feature -- Hooks
loop
a_sources.force (ic.item.name)
end
across l_node_api.recent_nodes (params) as ic loop
n := l_node_api.full_node (ic.item)
create ch.make (n.content_type, create {CMS_LOCAL_LINK}.make (n.title, "node/" + n.id.out), n.modification_date)
if n.creation_date ~ n.modification_date then
l_info := "new"
if not n.is_published then
l_info.append (" (unpublished)")
end
else
if n.is_trashed then
l_info := "trashed"
else
l_info := "updated"
l_src := a_changes.source
if attached a_changes.date as l_date then
l_nodes := l_node_api.recent_node_changes_before (params, l_date)
else
l_nodes := l_node_api.recent_node_changes_before (params, create {DATE_TIME}.make_now_utc)
end
across l_nodes as ic loop
n := ic.item
if l_src = Void or else l_src.is_case_insensitive_equal_general (n.content_type) then
n := l_node_api.full_node (n)
create ch.make (n.content_type, create {CMS_LOCAL_LINK}.make (n.title, "node/" + n.id.out), n.modification_date)
if n.creation_date ~ n.modification_date then
l_info := "new"
if not n.is_published then
l_info.append (" (unpublished)")
end
else
if n.is_trashed then
l_info := "deleted"
else
l_info := "updated"
if not n.is_published then
l_info.append (" (unpublished)")
end
end
end
ch.set_information (l_info)
ch.set_author (n.author)
a_changes.force (ch)
end
ch.set_information (l_info)
ch.set_author (n.author)
a_changes.force (ch)
end
end
end
@@ -62,14 +62,14 @@ feature -- Forms ...
sum.set_text_value (a_node.summary)
end
sum.set_label ("Summary")
sum.set_description ("This is the summary")
sum.set_description ("Text displayed in short view.")
sum.set_is_required (False)
create fset.make
-- Add summary
fset.extend (sum)
fset.extend_html_text("<br />")
fset.extend_html_text("<br/>")
-- Add content
fset.extend (ta)
@@ -300,6 +300,7 @@ feature -- Output
end
end
create s.make_empty
s.append ("<div class=%"cms-node node-" + a_node.content_type + "%">")
s.append ("<div class=%"info%"> ")
if attached a_node.author as l_author then
s.append (" by ")
@@ -339,6 +340,7 @@ feature -- Output
s.append ("</p>")
end
s.append ("</div>")
a_response.set_title (a_node.title)
a_response.set_main_content (s)
+4 -4
View File
@@ -54,7 +54,7 @@ feature -- Execution
node_api.has_permission_for_action_on_node ("edit", l_node, user)
then
f := new_edit_form (l_node, url (location, Void), "edit-" + l_type.name, l_type)
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.validation_actions.extend (agent edit_form_validate (?, b))
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
@@ -80,7 +80,7 @@ feature -- Execution
node_api.has_permission_for_action_on_node ("delete", l_node, user)
then
f := new_delete_form (l_node, url (location, Void), "delete-" + l_type.name, l_type)
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.process (Current)
fd := f.last_data
@@ -104,7 +104,7 @@ feature -- Execution
node_api.has_permission_for_action_on_node ("trash", l_node, user)
then
f := new_trash_form (l_node, url (location, Void), "trash-" + l_type.name, l_type)
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.process (Current)
fd := f.last_data
@@ -137,7 +137,7 @@ feature -- Execution
if has_permissions (<<"create any", "create " + l_type.name>>) then
if attached l_type.new_node (Void) as l_node then
f := new_edit_form (l_node, url (location, Void), "edit-" + l_type.name, l_type)
invoke_form_alter (f, fd)
hooks.invoke_form_alter (f, fd, Current)
if request.is_post_request_method then
f.validation_actions.extend (agent edit_form_validate (?, b))
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
@@ -56,7 +56,6 @@ feature -- Execution
process
-- Computed response message.
local
b: detachable STRING_8
nid: INTEGER_64
l_node: like node
do
@@ -90,6 +90,11 @@ feature -- Access
deferred
end
recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE]
-- List of recent changes, before `a_date', according to `params' settings.
deferred
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
require
@@ -59,6 +59,12 @@ feature -- Access: node
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE]
-- List of recent changes, before `a_date', according to `params' settings.
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- <Precursor>
do
@@ -128,7 +128,7 @@ feature -- Access
from
create l_parameters.make (2)
l_parameters.put (a_count, "rows")
l_parameters.put (a_count, "size")
l_parameters.put (a_lower, "offset")
sql_query (sql_select_recent_nodes, l_parameters)
sql_start
@@ -142,6 +142,34 @@ feature -- Access
end
end
recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE]
-- List of recent changes, before `a_date', according to `params' settings.
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
error_handler.reset
write_information_log (generator + ".nodes")
from
create l_parameters.make (3)
l_parameters.put (a_count, "size")
l_parameters.put (a_lower, "offset")
l_parameters.put (a_date, "date")
sql_query (sql_select_recent_node_changes_before, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_node as l_node then
Result.force (l_node)
end
sql_forth
end
end
node_by_id (a_id: INTEGER_64): detachable CMS_NODE
-- Retrieve node by id `a_id', if any.
local
@@ -402,7 +430,9 @@ feature {NONE} -- Queries
sql_select_node_by_id_and_revision: STRING = "SELECT nodes.nid, node_revisions.revision, nodes.type, node_revisions.title, node_revisions.summary, node_revisions.content, node_revisions.format, node_revisions.author, nodes.publish, nodes.created, node_revisions.changed, node_revisions.status FROM nodes INNER JOIN node_revisions ON nodes.nid = node_revisions.nid WHERE nodes.nid = :nid AND node_revisions.revision = :revision ORDER BY node_revisions.revision DESC;"
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes ORDER BY nid DESC, publish DESC LIMIT :rows OFFSET :offset ;"
sql_select_recent_nodes: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes ORDER BY nid DESC, publish DESC LIMIT :size OFFSET :offset ;"
sql_select_recent_node_changes_before: STRING = "SELECT nid, revision, type, title, summary, content, format, author, publish, created, changed, status FROM nodes WHERE changed <= :date ORDER BY changed DESC, nid DESC LIMIT :size OFFSET :offset ;"
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, status, author) VALUES (:revision, :type, :title, :summary, :content, :format, :publish, :created, :changed, :status, :author);"
-- SQL Insert to add a new node.
@@ -9,13 +9,6 @@ deferred class
inherit
CMS_HOOK
-- CMS_HOOK_WITH_WRAPPER
-- rename
-- wrapper as recent_changes_hook_wrapper
-- redefine
-- recent_changes_hook_wrapper
-- end
feature -- Invocation
populate_recent_changes (a_changes: CMS_RECENT_CHANGE_CONTAINER; a_sources: LIST [READABLE_STRING_8])
@@ -24,11 +17,4 @@ feature -- Invocation
deferred
end
--feature -- Wrapper
-- recent_changes_hook_wrapper: detachable CMS_RECENT_CHANGES_HOOK_WRAPPER
-- do
-- create Result.make (Current)
-- end
end
@@ -11,7 +11,8 @@ inherit
rename
module_api as recent_changes_api
redefine
register_hooks
register_hooks,
permissions
end
CMS_HOOK_MENU_SYSTEM_ALTER
@@ -35,6 +36,13 @@ feature -- Access
name: STRING = "recent_changes"
permissions: LIST [READABLE_STRING_8]
-- List of permission ids, used by this module, and declared.
do
Result := Precursor
Result.force ("view recent changes")
end
feature -- Access: router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
@@ -51,89 +59,147 @@ feature -- Handler
l_changes: CMS_RECENT_CHANGE_CONTAINER
l_sources: ARRAYED_LIST [READABLE_STRING_8]
dt, prev_dt: detachable DATE
ch: CMS_RECENT_CHANGE_ITEM
ch: detachable CMS_RECENT_CHANGE_ITEM
htdate: HTTP_DATE
l_content: STRING
l_form: CMS_FORM
l_select: WSF_FORM_SELECT
l_until_date: detachable DATE_TIME
l_filter_source: detachable READABLE_STRING_8
l_size: NATURAL_32
l_query: STRING
opt: WSF_FORM_SELECT_OPTION
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
create l_changes.make (25, Void, Void)
if attached {WSF_STRING} req.query_parameter ("date") as p_until_date then
create htdate.make_from_timestamp (p_until_date.value.to_integer_64)
l_until_date := htdate.date_time
-- l_until_date.second_add (-1)
end
if attached {WSF_STRING} req.query_parameter ("filter") as p_filter then
l_filter_source := p_filter.url_encoded_value
end
if attached {WSF_STRING} req.query_parameter ("size") as p_size then
l_size := p_size.integer_value.to_natural_32
end
if l_size = 0 then
l_size := 25
end
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if r.has_permission ("view recent changes") then
create l_changes.make (l_size, l_until_date, l_filter_source)
create l_content.make (1024)
if attached r.hooks.subscribers ({CMS_RECENT_CHANGES_HOOK}) as lst then
create l_sources.make (lst.count)
across
lst as ic
loop
if attached {CMS_RECENT_CHANGES_HOOK} ic.item as h then
h.populate_recent_changes (l_changes, l_sources)
end
end
create l_form.make (req.percent_encoded_path_info, "recent-changes")
create l_select.make ("source")
l_select.set_label ("Sources")
create opt.make ("", "...")
l_select.add_option (opt)
across
l_sources as ic
loop
create opt.make (ic.item, ic.item)
if l_filter_source /= Void and then ic.item.is_case_insensitive_equal (l_filter_source) then
opt.set_is_selected (True)
end
l_select.add_option (opt)
end
l_form.extend (l_select)
l_form.extend_html_text ("<br/>")
l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content)
end
l_changes.reverse_sort
l_content.append ("<table class=%"recent-changes%" style=%"border-spacing: 5px;%">")
l_content.append ("<thead>")
l_content.append ("<tr>")
l_content.append ("<th>Date</th>")
l_content.append ("<th>Source</th>")
l_content.append ("<th>Resource</th>")
l_content.append ("<th>User</th>")
l_content.append ("<th>Information</th>")
l_content.append ("</tr>")
l_content.append ("</thead>")
l_content.append ("<tbody>")
create l_content.make (1024)
if attached r.hooks.subscribers ({CMS_RECENT_CHANGES_HOOK}) as lst then
create l_sources.make (lst.count)
across
lst as ic
l_changes as ic
loop
if attached {CMS_RECENT_CHANGES_HOOK} ic.item as h then
h.populate_recent_changes (l_changes, l_sources)
ch := ic.item
dt := ch.date.date
if dt /~ prev_dt then
l_content.append ("<tr>")
l_content.append ("<td class=%"title%" colspan=%"5%">")
l_content.append (dt.formatted_out ("ddd, dd mmm yyyy"))
l_content.append ("</td>")
l_content.append ("</tr>")
end
prev_dt := dt
l_content.append ("<tr>")
l_content.append ("<td class=%"date%">")
create htdate.make_from_date_time (ch.date)
htdate.append_to_rfc1123_string (l_content)
l_content.append ("</td>")
l_content.append ("<td class=%"source%">" + ch.source + "</td>")
l_content.append ("<td class=%"resource%">")
l_content.append (r.link (ch.link.title, ch.link.location, Void))
l_content.append ("</td>")
l_content.append ("<td class=%"user%">")
if attached ch.author as u then
l_content.append (r.link (u.name, "user/" + u.id.out, Void))
end
l_content.append ("</td>")
l_content.append ("<td class=%"info%">")
if attached ch.information as l_info then
l_content.append ("<strong>" + l_info + "</strong> ")
end
l_content.append ("</td>")
l_content.append ("</tr>%N")
end
l_content.append ("</tbody>")
l_content.append ("</table>%N")
if ch /= Void then
if l_until_date /= Void then
l_content.append (" <a href=%"")
l_content.append (r.url (r.location, Void))
l_content.append ("?size=" + l_size.out + "%">&lt;&lt;</a> ")
end
if l_until_date /~ ch.date then
create htdate.make_from_date_time (ch.date)
create l_query.make_from_string ("size=" + l_size.out)
l_query.append ("&date=")
l_query.append (htdate.timestamp.out)
if l_filter_source /= Void then
l_query.append ("&filter=")
l_query.append (l_filter_source)
end
l_content.append ("<a href=%"")
l_content.append (r.url (r.location, create {CMS_API_OPTIONS}.make_from_manifest (<<["query", l_query]>>)))
l_content.append ("%">More ...</a>")
end
end
create l_form.make (req.percent_encoded_path_info, "recent-changes")
create l_select.make ("source")
l_select.set_label ("Sources")
across
l_sources as ic
loop
l_select.add_option (create {WSF_FORM_SELECT_OPTION}.make (ic.item, ic.item))
end
l_form.extend (l_select)
l_form.extend_html_text ("<br/>")
l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content)
end
l_changes.reverse_sort
l_content.append ("<table class=%"recent-changes%" style=%"border-spacing: 5px;%">")
l_content.append ("<thead>")
l_content.append ("<tr>")
l_content.append ("<th>Date</th>")
l_content.append ("<th>Source</th>")
l_content.append ("<th>Resource</th>")
l_content.append ("<th>User</th>")
l_content.append ("<th>Information</th>")
l_content.append ("</tr>")
l_content.append ("</thead>")
l_content.append ("<tbody>")
across
l_changes as ic
loop
ch := ic.item
dt := ch.date.date
if dt /~ prev_dt then
l_content.append ("<tr>")
l_content.append ("<td class=%"title%" colspan=%"5%">")
l_content.append (dt.formatted_out ("ddd, dd mmm yyyy"))
l_content.append ("</td>")
l_content.append ("</tr>")
r.set_main_content (l_content)
if l_until_date = Void then
r.set_title ("Recent changes")
else
create htdate.make_from_date_time (l_until_date)
r.set_title ("Recent changes before " + htdate.string)
end
prev_dt := dt
l_content.append ("<tr>")
l_content.append ("<td class=%"date%">")
create htdate.make_from_date_time (ch.date)
htdate.append_to_rfc1123_string (l_content)
l_content.append ("</td>")
l_content.append ("<td class=%"source%">" + ch.source + "</td>")
l_content.append ("<td class=%"resource%">")
l_content.append (r.link (ch.link.title, ch.link.location, Void))
l_content.append ("</td>")
l_content.append ("<td class=%"user%">")
if attached ch.author as u then
l_content.append (r.link (u.name, "user/" + u.id.out, Void))
end
l_content.append ("</td>")
l_content.append ("<td class=%"info%">")
if attached ch.information as l_info then
l_content.append ("<strong>" + l_info + "</strong> ")
end
l_content.append ("</td>")
l_content.append ("</tr>%N")
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
end
l_content.append ("</tbody>")
l_content.append ("</table>%N")
r.set_main_content (l_content)
r.set_title ("Last " + l_changes.count.out + " changes")
r.execute
end
@@ -172,9 +238,5 @@ feature -- Hook
a_menu_system.navigation_menu.extend (lnk)
end
-- populate_recent_changes (lst: LIST [CMS_RECENT_CHANGE_ITEM]; a_date: detachable DATE_TIME; a_limit: INTEGER)
-- do
-- end
end
-21
View File
@@ -24,27 +24,6 @@ feature -- Access
Result := all_subscribers.item (a_type)
end
--feature -- Invocation
-- invoke_module_hook (args: TUPLE; a_type: TYPE [CMS_HOOK])
-- -- Invoke module hook typed `a_type' with argument `args'.
-- do
-- if attached subscribers (a_type) as lst then
-- across
-- lst as ic
-- loop
-- if
-- attached {CMS_HOOK_WITH_WRAPPER} ic.item as hw and then
-- attached hw.wrapper as w
-- then
-- if w.valid_arguments (args) then
-- w.invoke (args)
-- end
-- end
-- end
-- end
-- end
feature -- Change
subscribe_to_hook (h: CMS_HOOK; a_hook_type: TYPE [CMS_HOOK])
+9 -1
View File
@@ -23,7 +23,12 @@ feature -- Access
html_options: detachable CMS_HTML_OPTIONS
-- Optional addition html options.
feature -- status report
feature -- Status report
is_empty: BOOLEAN
-- Is current block empty?
deferred
end
is_enabled: BOOLEAN
-- Is current block enabled?
@@ -93,4 +98,7 @@ feature -- Status report
end
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
+11 -5
View File
@@ -21,11 +21,10 @@ feature {NONE} -- Initialization
feature -- Access
name: READABLE_STRING_8
-- Block region name.
-- Block region name.
blocks: ARRAYED_LIST [CMS_BLOCK]
-- List of blocks.
-- List of blocks.
feature -- Element change
@@ -35,8 +34,15 @@ feature -- Element change
blocks.force (b)
end
;note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
remove (b: CMS_BLOCK)
require
has_block_b: blocks.has (b)
do
blocks.prune_all (b)
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
+7 -1
View File
@@ -49,6 +49,12 @@ feature -- Access
feature -- Status report
is_empty: BOOLEAN
-- Is current block empty?
do
Result := is_raw and content.is_empty
end
is_raw: BOOLEAN assign set_is_raw
-- Is raw?
-- If True, do not get wrapped it with block specific div
@@ -87,7 +93,7 @@ feature -- Conversion
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
+31 -5
View File
@@ -57,12 +57,39 @@ feature -- Access
root_path: detachable PATH
-- Root location for files universe.
resolved_location: PATH
-- Path of related file, taking into account `root_path' and `location'.
do
-- Process html generation
if attached root_path as l_root_path then
Result := l_root_path.extended_path (location)
else
Result := location
end
end
feature -- Status report
is_empty: BOOLEAN
-- Is current block empty?
do
Result := not exists
debug ("cms")
Result := True
end
end
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
exists: BOOLEAN
local
ut: FILE_UTILITIES
do
Result := ut.file_path_exists (resolved_location)
end
feature -- Element change
set_is_raw (b: BOOLEAN)
@@ -94,11 +121,7 @@ feature -- Conversion
ut: FILE_UTILITIES
do
-- Process html generation
if attached root_path as l_root_path then
p := l_root_path.extended_path (location)
else
p := location
end
p := resolved_location
if ut.file_path_exists (p) then
create f.make_with_path (p)
if f.exists and then f.is_access_readable then
@@ -145,4 +168,7 @@ feature -- Debug
end
Result.append ("%N")
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
+9
View File
@@ -31,6 +31,12 @@ feature -- Access
feature -- Status report
is_empty: BOOLEAN
-- Is current block empty?
do
Result := menu.is_empty
end
is_horizontal: BOOLEAN assign set_is_horizontal
-- Is horizontal layout for the menu?
@@ -72,4 +78,7 @@ feature -- Conversion
Result := a_theme.menu_html (menu, is_horizontal, html_options)
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
@@ -69,6 +69,9 @@ feature -- Access
feature -- Status report
is_empty: BOOLEAN = False
-- Is current block empty?
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
@@ -192,4 +195,7 @@ feature -- Debug
end
Result.append ("%N}")
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
+22 -20
View File
@@ -8,6 +8,7 @@ deferred class
CMS_EDITOR
feature -- Initialisation
load_assets : STRING
-- Loads all assest needed to show the editor
deferred
@@ -15,57 +16,55 @@ feature -- Initialisation
feature -- Javascript
javascript_replace_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
javascript_replace_textarea (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code that replaces a textarea with the editor. The editor instance should be saved in editor_variable
deferred
end
javascript_restore_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
javascript_restore_textarea (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code that restores a textarea
deferred
end
javascript_textarea_to_editor(a_textarea : WSF_FORM_TEXTAREA) : STRING
javascript_textarea_to_editor (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code to display the textarea as a WYSIWIG editor as soon as the document is loaded
do
Result := javascript_ready(javascript_replace_textarea (a_textarea))
Result := javascript_ready (javascript_replace_textarea (a_textarea))
end
javascript_textarea_to_editor_if_selected (a_textarea : WSF_FORM_TEXTAREA; a_select_field : WSF_FORM_SELECT; a_value : STRING) : STRING
javascript_textarea_to_editor_if_selected (a_textarea: WSF_FORM_TEXTAREA; a_select_field : WSF_FORM_SELECT; a_value : STRING) : STRING
-- Javascript code to display the textarea as a WYSIWIG editor if a_select_field has a_value
local
initial_replace_code, on_select_replace_code : STRING
initial_replace_code, on_select_replace_code: STRING
do
-- Javascript that replaces the textarea if a_value is selected at load time
initial_replace_code := javascript_ready(javascript_if_selected(a_select_field, a_value, javascript_replace_textarea(a_textarea)))
initial_replace_code := javascript_ready (javascript_if_selected (a_select_field, a_value, javascript_replace_textarea (a_textarea)))
-- Javascript code that replaces the textarea as soon as value is selected at a_select_field
on_select_replace_code := javascript_ready(
javascript_init_editor_variable(a_textarea) +
javascript_on_select(a_select_field, a_value,
javascript_init_editor_variable (a_textarea) +
javascript_on_select (a_select_field, a_value,
-- If a_value is selected, replace textarea
javascript_replace_textarea(a_textarea),
javascript_replace_textarea (a_textarea),
-- Otherwise restore it
javascript_restore_textarea(a_textarea)
javascript_restore_textarea (a_textarea)
)
)
Result := initial_replace_code + " " + on_select_replace_code
end
javascript_init_editor_variable(a_textarea : WSF_FORM_TEXTAREA) : STRING
javascript_init_editor_variable (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- Returns the javascript code that initializes a local variable to store the editor instance
do
Result := "var " + editor_variable(a_textarea) + "; "
Result := "var " + editor_variable (a_textarea) + "; "
end
javascript_if_selected(a_select_field : WSF_FORM_SELECT; a_value : STRING; a_code : STRING) : STRING
javascript_if_selected (a_select_field : WSF_FORM_SELECT; a_value : STRING; a_code : STRING) : STRING
-- Javascript that executes a_code if a_value is selected at a_select_field
do
Result := "if($('#" + field_id(a_select_field) + "').val() == %"" + a_value + "%"){ " + a_code + " }"
Result := "if($('#" + field_id (a_select_field) + "').val() == %"" + a_value + "%"){ " + a_code + " }"
end
javascript_ready (a_code : STRING) : STRING
@@ -77,8 +76,8 @@ feature -- Javascript
javascript_on_select (a_select_field : WSF_FORM_SELECT; a_value : STRING; a_then : STRING; a_else : STRING) : STRING
-- Javascript code that executes a_then if at the given select_field the given string value is selected, otherwise it executes a_else
do
Result := "$('#" + field_id(a_select_field) + "').change(function(){" +
javascript_if_selected(a_select_field, a_value, a_then) +
Result := "$('#" + field_id (a_select_field) + "').change(function(){" +
javascript_if_selected (a_select_field, a_value, a_then) +
"else{" +
a_else +
"}" +
@@ -100,7 +99,10 @@ feature -- Helper
editor_variable (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- Returns the variable name that stores the editor instance of the given textarea
do
Result := "editor_" + a_textarea.name
Result := "cms_ckeditor_" + a_textarea.name
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
+9 -4
View File
@@ -23,15 +23,20 @@ feature -- Javascript
javascript_replace_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- <Precursor>
do
-- Replaces the textarea with an editor instance. Save the instance in a variable
Result := editor_variable(a_textarea) + " = CKEDITOR.replace( '" + a_textarea.name + "' );"
-- Replaces the textarea with an editor instance. Save the instance in a variable
Result := "$(%"textarea[name="+ a_textarea.name +"]%").each(function() {"
Result.append (editor_variable (a_textarea) + " = CKEDITOR.replace(this);")
Result.append ("});")
end
javascript_restore_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- <Precursor>
do
-- Replaces the textarea with an editor instance. Save the instance in a variable
Result := "if (" + editor_variable(a_textarea) + " != undefined) " + editor_variable(a_textarea) + ".destroy();"
-- Replaces the textarea with an editor instance. Save the instance in a variable
Result := "if (" + editor_variable (a_textarea) + " != undefined) " + editor_variable (a_textarea) + ".destroy();"
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end
+2 -2
View File
@@ -19,7 +19,7 @@ feature -- Basic operation
prepare (a_response: CMS_RESPONSE)
do
a_response.invoke_form_alter (Current, Void)
a_response.hooks.invoke_form_alter (Current, Void, a_response)
end
process (a_response: CMS_RESPONSE)
@@ -29,7 +29,7 @@ feature -- Basic operation
on_prepared (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
do
a_response.invoke_form_alter (Current, fd)
a_response.hooks.invoke_form_alter (Current, fd, a_response)
end
on_processed (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
+7 -7
View File
@@ -24,15 +24,15 @@ feature -- Initialisation
make (a_name: like name)
-- <Precursor>
do
precursor(a_name)
Precursor (a_name)
-- By default we don't replace the textarea by an editor
editor := False;
editor_activated := False;
end
feature -- Access
editor : BOOLEAN
editor_activated : BOOLEAN
-- True if the textarea should be replaced by the editor. Default is false.
format_field : detachable WSF_FORM_SELECT
@@ -45,13 +45,13 @@ feature -- Editor
show_as_editor
-- The textarea will be replaced by a wysiwyg editor
do
editor := True
editor_activated := True
end
show_as_editor_if_selected (a_select_field : WSF_FORM_SELECT; a_value : STRING)
-- Replaces the textarea only if a_select_field has a_value (or the value gets selected)
do
editor := True
editor_activated := True
format_field := a_select_field
condition_value := a_value
end
@@ -61,8 +61,8 @@ feature -- Conversion
append_item_to_html (a_theme: WSF_THEME; a_html: STRING_8)
do
-- Add javascript to replace textarea with editor
precursor(a_theme, a_html)
if editor then
Precursor (a_theme, a_html)
if editor_activated then
a_html.append (load_assets)
a_html.append ("<script type=%"text/javascript%">");
if attached format_field as l_field and then attached condition_value as l_value then
+1 -1
View File
@@ -51,7 +51,7 @@ feature -- Hooks configuration
-- Module hooks configuration.
do
auto_subscribe_to_hooks (a_response)
a_response.subscribe_to_block_hook (Current)
a_response.hooks.subscribe_to_block_hook (Current)
end
feature -- Hooks
+12
View File
@@ -101,7 +101,19 @@ feature -- Custom
custom_value (a_name: READABLE_STRING_GENERAL; a_type: detachable READABLE_STRING_8): detachable READABLE_STRING_32
-- Data for name `a_name' and type `a_type' (or default if none).
local
s: STRING_32
do
if attached api as l_api then
create s.make_from_string_general ("custom_values")
if a_type /= Void then
s.append_character ('.')
s.append_string_general (a_type)
end
s.append_character ('.')
s.append_string_general (a_name)
Result := l_api.setup.text_item (s)
end
end
+44 -104
View File
@@ -403,19 +403,26 @@ feature -- Blocks initialization
create regions.make_caseless (5)
create l_table.make_caseless (10)
l_table["top"] := "top"
l_table["header"] := "header"
l_table["highlighted"] := "highlighted"
l_table["help"] := "help"
l_table["content"] := "content"
l_table["footer"] := "footer"
l_table["management"] := "sidebar_first"
l_table["navigation"] := "sidebar_first"
l_table["user"] := "sidebar_first"
l_table["bottom"] := "page_bottom"
l_table["top"] := block_region_preference ("top", "top")
l_table["header"] := block_region_preference ("header", "header")
l_table["highlighted"] := block_region_preference ("highlighted", "highlighted")
l_table["help"] := block_region_preference ("help", "help")
l_table["content"] := block_region_preference ("content", "content")
l_table["footer"] := block_region_preference ("footer", "footer")
l_table["management"] := block_region_preference ("management", "sidebar_first")
l_table["navigation"] := block_region_preference ("navigation", "sidebar_first")
l_table["user"] := block_region_preference ("user", "sidebar_first")
l_table["bottom"] := block_region_preference ("bottom", "page_bottom")
block_region_settings := l_table
end
block_region_preference (a_block_id: READABLE_STRING_8; a_default_region: READABLE_STRING_8): READABLE_STRING_8
-- Region associated with `a_block_id' in configuration, if any.
do
Result := setup.text_item_or_default ("blocks." + a_block_id + ".region", a_default_region)
end
feature -- Blocks regions
regions: STRING_TABLE [CMS_BLOCK_REGION]
@@ -430,12 +437,15 @@ feature -- Blocks regions
do
l_region_name := block_region_settings.item (b.name)
if l_region_name = Void then
if a_default_region /= Void then
if attached setup.text_item ("blocks." + b.name + ".region") as l_setup_name then
l_region_name := l_setup_name.as_string_8 -- FIXME: potential truncated string 32.
-- Remember for later.
block_region_settings.force (l_region_name, b.name)
elseif a_default_region /= Void then
l_region_name := a_default_region
else
-- Default .. put it in same named region
-- Maybe a bad idea
l_region_name := b.name.as_lower
end
end
@@ -483,7 +493,7 @@ feature -- Blocks
add_block (l_block, "sidebar_second")
end
invoke_block
hooks.invoke_block (Current)
debug ("cms")
add_block (create {CMS_CONTENT_BLOCK}.make ("made_with", Void, "Made with <a href=%"http://www.eiffel.com/%">EWF</a>", Void), "footer")
end
@@ -599,90 +609,6 @@ feature -- Hooks
hooks: CMS_HOOK_CORE_MANAGER
-- Manager handling hook subscriptions.
feature -- Hook: value alter
-- subscribe_to_value_table_alter_hook (h: CMS_HOOK_VALUE_TABLE_ALTER)
-- -- Add `h' as subscriber of value table alter hooks CMS_HOOK_VALUE_TABLE_ALTER.
-- do
-- hooks.subscribe_to_value_table_alter_hook (h)
-- end
invoke_value_table_alter (a_table: CMS_VALUE_TABLE)
-- Invoke value table alter hook for table `a_table'.
do
hooks.invoke_value_table_alter (a_table, Current)
end
feature -- Hook: response
-- subscribe_to_response_alter_hook (h: CMS_HOOK_RESPONSE_ALTER)
-- -- Add `h' as subscriber of response alter hooks CMS_HOOK_RESPONSE_ALTER.
-- do
-- hooks.subscribe_to_response_alter_hook (h)
-- end
invoke_response_alter (a_response: CMS_RESPONSE)
-- Invoke response alter hook for response `a_response'.
do
hooks.invoke_response_alter (a_response)
end
feature -- Hook: menu_system_alter
-- subscribe_to_menu_system_alter_hook (h: CMS_HOOK_MENU_SYSTEM_ALTER)
-- -- Add `h' as subscriber of menu system alter hooks CMS_HOOK_MENU_SYSTEM_ALTER.
-- do
-- hooks.subscribe_to_menu_system_alter_hook (h)
-- end
invoke_menu_system_alter (a_menu_system: CMS_MENU_SYSTEM)
-- Invoke menu system alter hook for menu `a_menu_system'.
do
hooks.invoke_menu_system_alter (menu_system, Current)
end
feature -- Hook: menu_alter
-- subscribe_to_menu_alter_hook (h: CMS_HOOK_MENU_ALTER)
-- -- Add `h' as subscriber of menu alter hooks CMS_HOOK_MENU_ALTER.
-- do
-- hooks.subscribe_to_menu_alter_hook (h)
-- end
invoke_menu_alter (a_menu: CMS_MENU)
-- Invoke menu alter hook for menu `a_menu'.
do
hooks.invoke_menu_alter (a_menu, Current)
end
feature -- Hook: form_alter
-- subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER)
-- -- Add `h' as subscriber of form alter hooks CMS_HOOK_FORM_ALTER.
-- do
-- hooks.subscribe_to_form_alter_hook (h)
-- end
invoke_form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA)
-- Invoke form alter hook for form `a_form' and associated data `a_form_data'
do
hooks.invoke_form_alter (a_form, a_form_data, Current)
end
feature -- Hook: block
subscribe_to_block_hook (h: CMS_HOOK_BLOCK)
-- Add `h' as subscriber of hooks CMS_HOOK_BLOCK.
do
hooks.subscribe_to_hook (h, {CMS_HOOK_BLOCK})
end
invoke_block
-- Invoke block hook in order to get block from modules.
do
hooks.invoke_block (Current)
end
feature -- Menu: change
add_to_main_menu (lnk: CMS_LINK)
@@ -704,9 +630,6 @@ feature -- Menu: change
add_to_menu (lnk: CMS_LINK; m: CMS_MENU)
do
-- if attached {CMS_LOCAL_LINK} lnk as l_local then
-- l_local.get_is_active (request)
-- end
m.extend (lnk)
end
@@ -815,13 +738,15 @@ feature -- Generation
prepare (page: CMS_HTML_PAGE)
local
lnk: CMS_LINK
l_region: CMS_BLOCK_REGION
l_menu_list_prepared: ARRAYED_LIST [CMS_LINK_COMPOSITE]
l_empty_blocks: detachable ARRAYED_LIST [CMS_BLOCK]
do
-- Menu
create {CMS_LOCAL_LINK} lnk.make ("Home", "")
lnk.set_weight (-10)
add_to_primary_menu (lnk)
invoke_menu_system_alter (menu_system)
hooks.invoke_menu_system_alter (menu_system, Current)
if api.enabled_modules.count = 0 then
add_to_primary_menu (create {CMS_LOCAL_LINK}.make ("Install", "admin/install"))
@@ -833,14 +758,29 @@ feature -- Generation
across
regions as reg_ic
loop
l_region := reg_ic.item
across
reg_ic.item.blocks as ic
l_region.blocks as ic
loop
if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then
l_menu_list_prepared.force (l_menu_block.menu)
prepare_links (l_menu_block.menu)
if l_menu_block.menu.is_empty then
if l_empty_blocks = Void then
create l_empty_blocks.make (1)
end
l_empty_blocks.force (l_menu_block)
end
end
end
if l_empty_blocks /= Void then
across
l_empty_blocks as ic
loop
l_region.remove (ic.item)
end
l_empty_blocks := Void
end
end
-- Prepare menu not in a block.
@@ -864,10 +804,10 @@ feature -- Generation
custom_prepare (page)
-- Cms response
invoke_response_alter (Current)
hooks.invoke_response_alter (Current)
-- Cms values
invoke_value_table_alter (values)
hooks.invoke_value_table_alter (values, Current)
-- Predefined values
page.register_variable (page, "page") -- DO NOT REMOVE