Initial implementation with Hooks, Regions and Templates

Updated Modules to support hooks, still work in progress.
This commit is contained in:
jvelilla
2014-11-03 12:40:54 -03:00
parent 5cb26f0b24
commit b11462105a
50 changed files with 1810 additions and 45 deletions

9
cms/src/hooks/cms_hook.e Normal file
View File

@@ -0,0 +1,9 @@
note
description: "Marker interface"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_HOOK
end

View File

@@ -0,0 +1,33 @@
note
description: "[
Summary description for {CMS_HOOK_AUTO_REGISTER}.
When inheriting from this class, the declared hooks are automatically
registered, otherwise, each descendant has to add it to the cms service
itself.
]"
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
deferred class
CMS_HOOK_AUTO_REGISTER
inherit
CMS_HOOK
feature -- Hook
hook_auto_register (a_response: CMS_RESPONSE)
do
if attached {CMS_HOOK_MENU_ALTER} Current as h_menu_alter then
a_response.add_menu_alter_hook (h_menu_alter)
end
if attached {CMS_HOOK_BLOCK} Current as h_block then
a_response.add_block_hook (h_block)
end
if attached {CMS_HOOK_FORM_ALTER} Current as h_block then
a_response.add_form_alter_hook (h_block)
end
end
end

View File

@@ -0,0 +1,23 @@
note
description: "Summary description for {CMS_HOOK_BLOCK}."
author: ""
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
deferred class
CMS_HOOK_BLOCK
inherit
CMS_HOOK
feature -- Hook
block_list: ITERABLE [like {CMS_BLOCK}.name]
deferred
end
get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE)
deferred
end
end

View File

@@ -0,0 +1,17 @@
note
description: "Describe how to alter a form before it's rendered"
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
deferred class
CMS_HOOK_FORM_ALTER
inherit
CMS_HOOK
feature -- Hook
form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_response: CMS_RESPONSE)
deferred
end
end

View File

@@ -0,0 +1,17 @@
note
description: "Describe how to alter a menu before it's rendered."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
deferred class
CMS_HOOK_MENU_ALTER
inherit
CMS_HOOK
feature -- Hook
menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
deferred
end
end

View File

@@ -0,0 +1,28 @@
note
description: "Describe how to alter generic values before they are rendered."
date: "$Date: 2014-10-23 08:30:11 -0300 (ju. 23 de oct. de 2014) $"
revision: "$Revision: 95980 $"
deferred class
CMS_HOOK_VALUE_ALTER
inherit
CMS_HOOK
feature -- Hook
value_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
deferred
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,97 @@
note
description: "Summary description for {WSF_CMS_COMMON_API}."
author: ""
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
deferred class
CMS_COMMON_API
inherit
WSF_API_UTILITIES
feature {NONE} -- Access
site_url: READABLE_STRING_8
do
Result := ""
end
base_url: detachable READABLE_STRING_8
-- Base url if any.
do
end
feature -- Access
user_link (u: CMS_USER): like link
do
Result := link (u.name, "/user/" + u.id.out, Void)
end
node_link (n: CMS_NODE): like link
do
Result := link (n.title, "/node/" + n.id.out, Void)
end
user_url (u: CMS_USER): like url
do
Result := url ("/user/" + u.id.out, Void)
end
node_url (n: CMS_NODE): like url
do
Result := url ("/node/" + n.id.out, Void)
end
feature -- Helper
is_empty (s: detachable READABLE_STRING_GENERAL): BOOLEAN
-- Is `s' is Void or empty ?
do
Result := s = Void or else s.is_empty
end
unix_timestamp (dt: DATE_TIME): INTEGER_64
do
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp (dt)
end
unix_timestamp_to_date_time (t: INTEGER_64): DATE_TIME
do
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (t)
end
string_unix_timestamp_to_date_time (s: READABLE_STRING_8): DATE_TIME
do
if s.is_integer_64 then
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (s.to_integer_64)
else
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (0)
end
end
feature {NONE} -- Implementation
options_boolean (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING; dft: BOOLEAN): BOOLEAN
do
if attached {BOOLEAN} opts.item (k) as h then
Result := h
else
Result := dft
end
end
options_string (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING): detachable STRING
do
if attached {STRING} opts.item (k) as s then
Result := s
end
end
-- html_encoder: HTML_ENCODER
-- once ("thread")
-- create Result
-- end
end

View File

@@ -0,0 +1,28 @@
note
description: "Summary description for {CMS_BLOCK}."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
deferred class
CMS_BLOCK
feature -- Access
name: READABLE_STRING_8
deferred
end
title: detachable READABLE_STRING_32
deferred
end
feature -- status report
is_enabled: BOOLEAN
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
deferred
end
end

View File

@@ -0,0 +1,42 @@
note
description: "Summary description for {CMS_BLOCK_REGION}."
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
class
CMS_BLOCK_REGION
create
make
feature {NONE} -- Initialization
make (a_name: like name)
do
name := a_name
create blocks.make (1)
end
feature -- Access
name: READABLE_STRING_8
blocks: ARRAYED_LIST [CMS_BLOCK]
feature -- Element change
extend (b: CMS_BLOCK)
do
blocks.force (b)
end
;note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,74 @@
note
description: "Summary description for {CMS_CONTENT_BLOCK}."
author: ""
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
revision: "$Revision: 96018 $"
class
CMS_CONTENT_BLOCK
inherit
CMS_BLOCK
create
make,
make_raw
feature {NONE} -- Initialization
make (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
do
is_enabled := True
name := a_name
title := a_title
content := a_content
format := a_format
end
make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
do
make (a_name, a_title, a_content, a_format)
set_is_raw (True)
end
feature -- Access
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
content: READABLE_STRING_8
format: CONTENT_FORMAT
feature -- Status report
is_raw: BOOLEAN
-- Is raw?
-- If True, do not get wrapped it with block specific div
feature -- Element change
set_is_raw (b: BOOLEAN)
do
is_raw := b
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := content
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,41 @@
note
description: "Summary description for {CMS_MENU_BLOCK}."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
class
CMS_MENU_BLOCK
inherit
CMS_BLOCK
create
make
feature {NONE} -- Initialization
make (a_menu: like menu)
do
is_enabled := True
menu := a_menu
name := a_menu.name
title := a_menu.title
end
feature -- Access
menu: CMS_MENU
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
is_horizontal: BOOLEAN
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := a_theme.menu_html (menu, is_horizontal)
end
end

View File

@@ -0,0 +1,89 @@
note
description: "Summary description for {CMS_VALUE_TABLE}."
date: "$Date: 2014-10-23 08:30:11 -0300 (ju. 23 de oct. de 2014) $"
revision: "$Revision: 95980 $"
class
CMS_VALUE_TABLE
inherit
TABLE_ITERABLE [detachable ANY, READABLE_STRING_GENERAL]
create
make
feature {NONE} -- Initialization
make (nb: INTEGER)
do
create table.make (nb)
end
feature -- Access
count: INTEGER
-- Number of items.
do
Result := table.count
end
item (key: READABLE_STRING_GENERAL): detachable ANY
-- Item associated with `key', if present
-- otherwise default value of type `G'.
note
option: stable
do
Result := table.item (key)
end
has (key: READABLE_STRING_GENERAL): BOOLEAN
-- Has item associated with key `key'?
do
Result := table.has (key)
end
new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL]
-- <Precursor>
do
Result := table.new_cursor
end
feature -- Element change
put (new: detachable ANY; key: READABLE_STRING_GENERAL)
-- Insert `new' with `key' if there is no other item
-- associated with the same key.
do
table.put (new, key)
end
force (new: detachable ANY; key: READABLE_STRING_GENERAL)
-- Update table so that `new' will be the item associated
-- with `key'.
do
table.force (new, key)
end
remove (key: READABLE_STRING_GENERAL)
do
table.remove (key)
end
feature {NONE} -- Duplication
table: STRING_TABLE [detachable ANY]
invariant
table_set: table /= Void
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,64 @@
note
description: "Summary description for {CMS_FORMATS}."
author: ""
date: "$Date: 2014-10-16 04:45:23 -0300 (ju. 16 de oct. de 2014) $"
revision: "$Revision: 95932 $"
class
CMS_FORMATS
feature -- Access
format (a_name: like {CONTENT_FORMAT}.name): detachable CONTENT_FORMAT
do
across
all_formats as c
until
Result /= Void
loop
if c.item.name.same_string (a_name) then
Result := c.item
end
end
end
all_formats: LIST [CONTENT_FORMAT]
once
create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (3)
Result.force (plain_text)
Result.force (full_html)
Result.force (filtered_html)
end
default_format: CONTENT_FORMAT
do
Result := plain_text --FIXME
end
plain_text: PLAIN_TEXT_CONTENT_FORMAT
once
create Result
end
full_html: FULL_HTML_CONTENT_FORMAT
once
create Result
end
filtered_html: FILTERED_HTML_CONTENT_FORMAT
once
create Result
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,42 @@
note
description: "Summary description for {CMS_FORM}."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
class
CMS_FORM
inherit
WSF_FORM
rename
process as process_form
end
create
make
feature -- Basic operation
prepare (a_response: CMS_RESPONSE)
do
a_response.call_form_alter_hooks (Current, Void)
end
process (a_response: CMS_RESPONSE)
do
process_form (a_response.request, agent on_prepared (a_response, ?), agent on_processed (a_response, ?))
end
on_prepared (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
do
a_response.call_form_alter_hooks (Current, fd)
end
on_processed (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
do
if not fd.is_valid or fd.has_error then
a_response.report_form_errors (fd)
end
end
end

View File

@@ -0,0 +1,88 @@
note
description: "Describe the navigation menus."
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
revision: "$Revision: 95708 $"
class
CMS_MENU_SYSTEM
inherit
ITERABLE [CMS_MENU]
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make
-- Create a predefined manu system
do
to_implement ("Refactor, take the info from a Database or Configuration file.")
create items.make (5)
force (create {CMS_MENU}.make ("main-menu", 3))
force (create {CMS_MENU}.make_with_title ("management", "Management", 3))
force (create {CMS_MENU}.make_with_title ("navigation", "Navigation", 3))
force (create {CMS_MENU}.make_with_title ("user", "User", 3))
end
feature -- Access
item (n: like {CMS_MENU}.name): CMS_MENU
local
m: detachable CMS_MENU
do
m := items.item (n)
if m = Void then
create m.make (n, 3)
force (m)
end
Result := m
end
main_menu: CMS_MENU
do
Result := item ("main-menu")
end
management_menu: CMS_MENU
do
Result := item ("management")
end
navigation_menu: CMS_MENU
do
Result := item ("navigation")
end
user_menu: CMS_MENU
do
Result := item ("user")
end
primary_tabs: CMS_MENU
do
Result := item ("primary-tabs")
end
feature -- Change
force (m: CMS_MENU)
do
items.force (m, m.name)
end
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_MENU]
-- Fresh cursor associated with current structure.
do
Result := items.new_cursor
end
feature {NONE} -- Implementation
items: HASH_TABLE [CMS_MENU, like {CMS_MENU}.name]
-- items: ARRAYED_LIST [CMS_MENU]
end

View File

@@ -74,4 +74,11 @@ feature {NONE} -- Implementation: routes
a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
end
end

View File

@@ -50,7 +50,7 @@ feature -- HTTP Methods
if attached req.query_parameter ("prompt") as l_prompt then
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
else
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/basic_auth/logoff")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
l_page.execute
end

View File

@@ -27,6 +27,17 @@ feature -- Router
deferred
end
feature -- Hooks configuration
register_hooks (a_response: CMS_RESPONSE)
-- Module hooks configuration.
require
is_enabled: is_enabled
deferred
end
feature -- Filter
filters: detachable LIST [WSF_FILTER]

View File

@@ -70,7 +70,7 @@ feature -- HTTP Methods
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_content")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (l_node.content, "node_content")
l_page.add_variable (l_id.value, "id")
l_page.execute
@@ -78,7 +78,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -96,14 +96,14 @@ feature -- HTTP Methods
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -127,7 +127,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -140,7 +140,7 @@ feature -- Error
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found

View File

@@ -69,7 +69,7 @@ feature -- HTTP Methods
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup,"modules/node")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (l_node, "node")
l_page.execute
else
@@ -96,7 +96,7 @@ feature -- HTTP Methods
elseif l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
end
else
@@ -131,7 +131,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -151,7 +151,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -165,7 +165,7 @@ feature -- Error
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found
@@ -186,7 +186,7 @@ feature {NONE} -- Node
l_page: CMS_RESPONSE
do
if attached current_user_name (req) then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (setup.is_html, "html")
l_page.add_variable (setup.is_web, "web")
l_page.execute

View File

@@ -69,7 +69,7 @@ feature -- HTTP Methods
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_summary")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (l_id.value, "id")
l_page.add_variable (l_node.summary, "node_summary")
l_page.execute
@@ -77,7 +77,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -95,14 +95,14 @@ feature -- HTTP Methods
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -125,7 +125,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -140,7 +140,7 @@ feature -- Error
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found

View File

@@ -69,7 +69,7 @@ feature -- HTTP Methods
-- Existing node
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_title")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (l_node.title, "node_title")
l_page.add_variable (l_id.value, "id")
l_page.execute
@@ -77,7 +77,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -94,14 +94,14 @@ feature -- HTTP Methods
if l_method.is_case_insensitive_equal ("PUT") then
do_put (req, res)
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
end
else
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -125,7 +125,7 @@ feature -- HTTP Methods
do_error (req, res, l_id)
end
else
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
end
else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
@@ -139,7 +139,7 @@ feature -- Error
local
l_page: CMS_RESPONSE
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/error")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (req.absolute_script_url (req.path_info), "request")
if a_id.is_integer then
-- resource not found

View File

@@ -52,7 +52,7 @@ feature -- HTTP Methods
-- At the moment the template is hardcoded, but we can
-- get them from the configuration file and load them into
-- the setup class.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/nodes")
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup)
l_page.add_variable (api_service.nodes, "nodes")
l_page.execute
end

View File

@@ -10,6 +10,11 @@ inherit
CMS_MODULE
CMS_HOOK_MENU_ALTER
CMS_HOOK_BLOCK
create
make
@@ -115,4 +120,40 @@ feature {NONE} -- Implementation: routes
a_router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
a_response.add_menu_alter_hook (Current)
a_response.add_block_hook (Current)
end
block_list: ITERABLE [like {CMS_BLOCK}.name]
do
Result := <<"node-info">>
end
get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE)
-- local
-- b: CMS_CONTENT_BLOCK
do
-- if
-- a_execution.is_front and then
-- attached a_execution.user as u
-- then
-- create b.make ("node-info", "Node", "Node ...", a_execution.formats.plain_text)
-- a_execution.add_block (b, Void)
-- end
end
menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
perms: detachable ARRAYED_LIST [READABLE_STRING_8]
do
create lnk.make ("node", "/node")
a_menu_system.navigation_menu.extend (lnk)
end
end

View File

@@ -25,7 +25,7 @@ feature -- Basic operations
execute_next (req, res)
else
log.write_critical (generator + ".execute" + setup.error_handler.as_string_representation )
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
(create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute
setup.error_handler.reset
end
end

View File

@@ -48,7 +48,7 @@ feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
(create {HOME_CMS_RESPONSE}.make (req, res, setup,"layout2")).execute
(create {HOME_CMS_RESPONSE}.make (req, res, setup)).execute
end
end

View File

@@ -14,22 +14,44 @@ inherit
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup; a_template: like template)
make(req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup)
do
status_code := {HTTP_STATUS_CODE}.ok
setup := a_setup
request := req
response := res
template := a_template
create header.make
create values.make (3)
initialize
end
initialize
do
get_theme
create menu_system.make
initialize_block_region_settings
register_hooks
end
register_hooks
local
l_module: CMS_MODULE
l_available_modules: CMS_MODULE_COLLECTION
do
-- log.write_debug (generator + ".register_hooks")
l_available_modules := setup.modules
across
l_available_modules as ic
loop
l_module := ic.item
if l_module.is_enabled then
l_module.register_hooks (Current)
end
end
end
feature -- Access
request: WSF_REQUEST
@@ -50,8 +72,9 @@ feature -- Access
main_content: detachable STRING_8
template: READABLE_STRING_32
-- Current template.
values: CMS_VALUE_TABLE
-- Associated values indexed by string name.
feature -- Element change
@@ -71,6 +94,423 @@ feature -- Element change
main_content := s
end
feature -- Formats
formats: CMS_FORMATS
once
create Result
end
feature -- Menu
menu_system: CMS_MENU_SYSTEM
main_menu: CMS_MENU
do
Result := menu_system.main_menu
end
management_menu: CMS_MENU
do
Result := menu_system.management_menu
end
navigation_menu: CMS_MENU
do
Result := menu_system.navigation_menu
end
user_menu: CMS_MENU
do
Result := menu_system.user_menu
end
primary_tabs: CMS_MENU
do
Result := menu_system.primary_tabs
debug
end
end
feature -- Blocks initialization
initialize_block_region_settings
local
l_table: like block_region_settings
do
create regions.make_caseless (5)
-- FIXME: let the user choose ...
create l_table.make_caseless (10)
l_table["page_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"] := "first_sidebar"
l_table["navigation"] := "first_sidebar"
l_table["user"] := "first_sidebar"
l_table["page_bottom"] := "page_bottom"
block_region_settings := l_table
end
feature -- Blocks regions
regions: STRING_TABLE [CMS_BLOCK_REGION]
-- Layout regions, that contains blocks.
block_region_settings: STRING_TABLE [STRING]
block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION
-- Region associated with block `b', or else `a_default_region' if provided.
local
l_region_name: detachable READABLE_STRING_8
do
l_region_name := block_region_settings.item (b.name)
if l_region_name = Void then
if 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
if attached regions.item (l_region_name) as res then
Result := res
else
create Result.make (l_region_name)
regions.force (Result, l_region_name)
end
end
feature -- Blocks
add_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8)
-- Add block `b' to associated region or `a_default_region' if provided.
local
l_region: detachable like block_region
do
l_region := block_region (b, a_default_region)
l_region.extend (b)
end
get_blocks
do
fixme ("find a way to have this in configuration or database, and allow different order")
add_block (top_header_block, "header")
add_block (header_block, "header")
if attached message_block as m then
add_block (m, "content")
end
-- FIXME: avoid hardcoded html! should be only in theme.
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("top_content_anchor", Void, "<a id=%"main-content%"></a>%N", formats.full_html), "content")
if attached page_title as l_page_title then
-- FIXME: avoid hardcoded html! should be only in theme.
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("page_title", Void, "<h1 id=%"page-title%" class=%"title%">"+ l_page_title +"</h1>%N", formats.full_html), "content")
end
if attached primary_tabs_block as m then
add_block (m, "content")
end
add_block (content_block, "content")
if attached management_menu_block as l_block then
add_block (l_block, "first_sidebar")
end
if attached navigation_menu_block as l_block then
add_block (l_block, "first_sidebar")
end
if attached user_menu_block as l_block then
add_block (l_block, "first_sidebar")
end
if attached footer_block as l_block then
add_block (l_block, "footer")
end
hook_block_view
end
main_menu_block: detachable CMS_MENU_BLOCK
do
if attached main_menu as m and then not m.is_empty then
create Result.make (m)
end
end
management_menu_block: detachable CMS_MENU_BLOCK
do
if attached management_menu as m and then not m.is_empty then
create Result.make (m)
end
end
navigation_menu_block: detachable CMS_MENU_BLOCK
do
if attached navigation_menu as m and then not m.is_empty then
create Result.make (m)
end
end
user_menu_block: detachable CMS_MENU_BLOCK
do
if attached user_menu as m and then not m.is_empty then
create Result.make (m)
end
end
primary_tabs_block: detachable CMS_MENU_BLOCK
do
if attached primary_tabs as m and then not m.is_empty then
create Result.make (m)
end
end
top_header_block: CMS_CONTENT_BLOCK
local
s: STRING
do
fixme ("Avoid Hardcoded HTML")
-- create s.make_from_string ("<a href=%""+ url ("/", Void) +"%"><img id=%"logo%" src=%"" + logo_location + "%"/></a><div id=%"title%">" + html_encoded (site_name) + "</div>")
create s.make_empty
s.append ("<div id=%"menu-bar%">")
s.append (theme.menu_html (main_menu, True))
s.append ("</div>")
create Result.make ("top_header", Void, s, formats.full_html)
Result.set_is_raw (True)
end
header_block: CMS_CONTENT_BLOCK
local
s: STRING
do
create s.make_empty
create Result.make ("header", Void, s, formats.full_html)
Result.set_is_raw (True)
end
message_block: detachable CMS_CONTENT_BLOCK
do
if attached message as m and then not m.is_empty then
create Result.make ("message", Void, "<div id=%"message%">" + m + "</div>", formats.full_html)
Result.set_is_raw (True)
end
end
content_block: CMS_CONTENT_BLOCK
local
s: STRING
do
if attached main_content as l_content then
s := l_content
else
s := ""
debug
s := "No Content"
end
end
create Result.make ("content", Void, s, formats.full_html)
Result.set_is_raw (True)
end
footer_block: CMS_CONTENT_BLOCK
local
s: STRING
do
create s.make_empty
s.append ("Made with <a href=%"http://www.eiffel.com/%">EWF</a>")
create Result.make ("made_with", Void, s, formats.full_html)
end
feature -- Hook: value alter
add_value_alter_hook (h: like value_alter_hooks.item)
local
lst: like value_alter_hooks
do
lst := value_alter_hooks
if lst = Void then
create lst.make (1)
value_alter_hooks := lst
end
if not lst.has (h) then
lst.force (h)
end
end
value_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_VALUE_ALTER]
call_value_alter_hooks (m: CMS_VALUE_TABLE)
do
if attached value_alter_hooks as lst then
across
lst as c
loop
c.item.value_alter (m, Current)
end
end
end
feature -- Hook: menu_alter
add_menu_alter_hook (h: like menu_alter_hooks.item)
local
lst: like menu_alter_hooks
do
lst := menu_alter_hooks
if lst = Void then
create lst.make (1)
menu_alter_hooks := lst
end
if not lst.has (h) then
lst.force (h)
end
end
menu_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_MENU_ALTER]
call_menu_alter_hooks (m: CMS_MENU_SYSTEM )
do
if attached menu_alter_hooks as lst then
across
lst as c
loop
c.item.menu_alter (m, Current)
end
end
end
feature -- Hook: form_alter
add_form_alter_hook (h: like form_alter_hooks.item)
local
lst: like form_alter_hooks
do
lst := form_alter_hooks
if lst = Void then
create lst.make (1)
form_alter_hooks := lst
end
if not lst.has (h) then
lst.force (h)
end
end
form_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_FORM_ALTER]
call_form_alter_hooks (f: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; )
do
if attached form_alter_hooks as lst then
across
lst as c
loop
c.item.form_alter (f, a_form_data, Current)
end
end
end
feature -- Hook: block
add_block_hook (h: like block_hooks.item)
local
lst: like block_hooks
do
lst := block_hooks
if lst = Void then
create lst.make (1)
block_hooks := lst
end
if not lst.has (h) then
lst.force (h)
end
end
block_hooks: detachable ARRAYED_LIST [CMS_HOOK_BLOCK]
hook_block_view
do
if attached block_hooks as lst then
across
lst as c
loop
across
c.item.block_list as blst
loop
c.item.get_block_view (blst.item, Current)
end
end
end
end
feature -- Message
add_message (a_msg: READABLE_STRING_8; a_category: detachable READABLE_STRING_8)
local
m: like message
do
m := message
if m = Void then
create m.make (a_msg.count + 9)
message := m
end
if a_category /= Void then
m.append ("<li class=%""+ a_category +"%">")
else
m.append ("<li>")
end
m.append (a_msg + "</li>")
end
add_notice_message (a_msg: READABLE_STRING_8)
do
add_message (a_msg, "notice")
end
add_warning_message (a_msg: READABLE_STRING_8)
do
add_message (a_msg, "warning")
end
add_error_message (a_msg: READABLE_STRING_8)
do
add_message (a_msg, "error")
end
add_success_message (a_msg: READABLE_STRING_8)
do
add_message (a_msg, "success")
end
report_form_errors (fd: WSF_FORM_DATA)
require
has_error: not fd.is_valid
do
if attached fd.errors as errs then
across
errs as err
loop
if attached err.item as e then
if attached e.field as l_field then
if attached e.message as e_msg then
add_error_message (e_msg) --"Field [" + l_field.name + "] is invalid. " + e_msg)
else
add_error_message ("Field [" + l_field.name + "] is invalid.")
end
elseif attached e.message as e_msg then
add_error_message (e_msg)
end
end
end
end
end
message: detachable STRING_8
feature -- Theme
theme: CMS_THEME
@@ -86,7 +526,7 @@ feature -- Theme
create l_info.make_default
end
if l_info.engine.is_case_insensitive_equal_general ("smarty") then
create {SMARTY_CMS_THEME} theme.make (setup, l_info, template)
create {SMARTY_CMS_THEME} theme.make (setup, l_info)
else
create {DEFAULT_CMS_THEME} theme.make (setup, l_info)
end
@@ -111,6 +551,54 @@ feature -- Generation
do
common_prepare (page)
custom_prepare (page)
-- Cms values
call_value_alter_hooks (values)
-- Values Associated with current Execution object.
across
values as ic
loop
page.register_variable (ic.item, ic.key)
end
-- Specific values
page.register_variable (request.absolute_script_url (""), "site_url")
-- Additional lines in <head ../>
call_menu_alter_hooks (menu_system)
prepare_menu_system (menu_system)
get_blocks
across
regions as reg_ic
loop
across
reg_ic.item.blocks as ic
loop
if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then
recursive_get_active (l_menu_block.menu, request)
end
end
end
if attached title as l_title then
page.set_title (l_title)
else
page.set_title ("CMS::" + request.path_info)
end
-- blocks
across
regions as reg_ic
loop
across
reg_ic.item.blocks as ic
loop
page.add_to_region (theme.block_html (ic.item), reg_ic.item.name)
end
end
end
common_prepare (page: CMS_HTML_PAGE)
@@ -129,6 +617,65 @@ feature -- Generation
end
prepare_menu_system (a_menu_system: CMS_MENU_SYSTEM)
do
across
a_menu_system as c
loop
prepare_links (c.item)
end
end
prepare_links (a_menu: CMS_LINK_COMPOSITE)
local
to_remove: ARRAYED_LIST [CMS_LINK]
do
create to_remove.make (0)
across
a_menu as c
loop
if attached {CMS_LOCAL_LINK} c.item as lm then
-- if attached lm.permission_arguments as perms and then not has_permissions (perms) then
-- to_remove.force (lm)
-- else
-- if lm.permission_arguments is Void , this is permitted
-- lm.get_is_active (request)
if attached {CMS_LINK_COMPOSITE} lm as comp then
prepare_links (comp)
end
-- end
elseif attached {CMS_LINK_COMPOSITE} c.item as comp then
prepare_links (comp)
end
end
across
to_remove as c
loop
a_menu.remove (c.item)
end
end
recursive_get_active (a_comp: CMS_LINK_COMPOSITE; req: WSF_REQUEST)
-- Update the active status recursively on `a_comp'.
local
ln: CMS_LINK
do
if attached a_comp.items as l_items then
across
l_items as ic
loop
ln := ic.item
if attached {CMS_LOCAL_LINK} ln as l_local then
-- l_local.get_is_active (request)
end
if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then
recursive_get_active (l_comp, req)
end
end
end
end
feature -- Custom Variables
variables: detachable STRING_TABLE[ANY]

View File

@@ -24,9 +24,18 @@ feature -- Access
page_template: CMS_TEMPLATE
deferred
end
feature -- Conversion
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
-- Render Menu as HTML.
-- A theme will define a menu.tpl
deferred
end
block_html (a_block: CMS_BLOCK): STRING_8
deferred
end
page_html (page: CMS_HTML_PAGE): STRING_8
-- Render `page' as html.
deferred
@@ -34,6 +43,67 @@ feature -- Conversion
feature {NONE} -- Implementation
append_cms_link_to (lnk: CMS_LINK; s: STRING_8)
local
cl: STRING
do
create cl.make_empty
if lnk.is_active then
cl.append ("active ")
end
if lnk.is_expandable then
cl.append ("expandable ")
end
if lnk.is_expanded then
cl.append ("expanded ")
end
if cl.is_empty then
s.append ("<li>")
else
s.append ("<li class=%""+ cl + "%">")
end
-- s.append ("<a href=%"" + url (lnk.location, lnk.options) + "%">" + html_encoded (lnk.title) + "</a>")
if
-- (lnk.is_expanded or lnk.is_collapsed) and then
attached lnk.children as l_children
then
s.append ("<ul>%N")
across
l_children as c
loop
append_cms_link_to (c.item, s)
end
s.append ("</ul>")
end
s.append ("</li>")
end
feature -- Encoders
url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
local
enc: URL_ENCODER
do
create enc
if s /= Void then
Result := enc.general_encoded_string (s)
else
create Result.make_empty
end
end
html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
local
enc: HTML_ENCODER
do
create enc
if s /= Void then
Result := enc.general_encoded_string (s)
else
create Result.make_empty
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"

View File

@@ -60,7 +60,46 @@ feature -- Conversion
prepare (page: CMS_HTML_PAGE)
do
-- page.add_style (url ("/theme/style.css", Void), Void)
end
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
do
create Result.make_from_string ("<div id=%""+ a_menu.name +"%" class=%"menu%">")
if is_horizontal then
Result.append ("<ul class=%"horizontal%" >%N")
else
Result.append ("<ul class=%"vertical%" >%N")
end
across
a_menu as c
loop
append_cms_link_to (c.item, Result)
end
Result.append ("</ul>%N")
Result.append ("</div>")
end
block_html (a_block: CMS_BLOCK): STRING_8
local
s: STRING
do
if attached {CMS_CONTENT_BLOCK} a_block as l_content_block and then l_content_block.is_raw then
create s.make_empty
if attached l_content_block.title as l_title then
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
end
s.append (l_content_block.to_html (Current))
else
create s.make_from_string ("<div class=%"block%" id=%"" + a_block.name + "%">")
if attached a_block.title as l_title then
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
end
s.append ("<div class=%"inside%">")
s.append (a_block.to_html (Current))
s.append ("</div>")
s.append ("</div>")
end
Result := s
end
page_html (page: CMS_HTML_PAGE): STRING_8

View File

@@ -10,16 +10,17 @@ class
inherit
CMS_THEME
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make (a_setup: like setup; a_info: like information; a_template: like template)
make (a_setup: like setup; a_info: like information;)
do
setup := a_setup
information := a_info
template := a_template
if attached a_info.item ("template_dir") as s then
templates_directory := a_setup.theme_location.extended (s)
else
@@ -28,15 +29,12 @@ feature {NONE} -- Initialization
ensure
setup_set: setup = a_setup
information_set: information = a_info
template_set: template = a_template
end
feature -- Access
name: STRING = "smarty-CMS"
template: STRING;
templates_directory: PATH
information: CMS_THEME_INFORMATION
@@ -59,7 +57,7 @@ feature -- Access
i := i + 1
end
else
l_regions := <<"header", "content", "footer", "first_sidebar", "second_sidebar">>
l_regions := <<"top","header", "content", "footer", "first_sidebar", "second_sidebar","bottom">>
end
internaL_regions := l_regions
end
@@ -72,7 +70,7 @@ feature -- Access
do
tpl := internal_page_template
if tpl = Void then
create tpl.make (template, Current)
create tpl.make ("page", Current)
internal_page_template := tpl
end
Result := tpl
@@ -80,6 +78,21 @@ feature -- Access
feature -- Conversion
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
-- Render Menu as HTML.
-- A theme will define a menu.tpl
do
to_implement ("Add implementation")
Result := "to be implemented"
end
block_html (a_block: CMS_BLOCK): STRING_8
do
to_implement ("Add implementation")
Result := "to be implemented"
end
prepare (page: CMS_HTML_PAGE)
do
end