Fixed and improved various issue in admin module (especially the Role editing which was not working as expected.)
Added CMS_MODULE.permissions to allow module to declare the potential permissions. Added support for CMS_LINK.is_forbidden, in relation with CMS_LOCAL_LINK.permission_arguments. Split link "username (Logout)" into 2 links "username" and "logout". Fixed/Changed the way auth modules alter the logout link based on "(Logout)" title, by safer solution based on `location' of the link. Fixed usage of WSF_REQUEST.path_info by using percent_encoded_path_info which is not non unicode path info to be used most of the time. Merged CMS_REPONSE.variables and CMS_REPONSE.values . When possible, prefer usage of CMS_RESPONSE.user instead of CMS_REQUEST_UTIL.current_user (WSF_REQUEST) whenever it is possible. When possible, prefer usage of CMS_RESPONSE.location, rather than usage of WSF_REQUEST.(percent_encoded_)path_info . Code cleaning.
This commit is contained in:
@@ -171,6 +171,13 @@ feature -- Access: roles and permissions
|
||||
deferred
|
||||
end
|
||||
|
||||
role_permissions: LIST [READABLE_STRING_8]
|
||||
-- Possible known role permissions.
|
||||
deferred
|
||||
ensure
|
||||
object_comparison: Result.object_comparison
|
||||
end
|
||||
|
||||
feature -- Change: roles and permissions
|
||||
|
||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||
|
||||
@@ -99,6 +99,12 @@ feature -- Access: roles and permissions
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0)
|
||||
end
|
||||
|
||||
role_permissions: LIST [READABLE_STRING_8]
|
||||
-- Possible known permissions.
|
||||
do
|
||||
create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0)
|
||||
end
|
||||
|
||||
feature -- Change: roles and permissions
|
||||
|
||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||
|
||||
@@ -503,6 +503,27 @@ feature -- Access: roles and permissions
|
||||
end
|
||||
end
|
||||
|
||||
role_permissions: LIST [READABLE_STRING_8]
|
||||
-- Possible known permissions.
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".role_permissions")
|
||||
|
||||
create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0)
|
||||
Result.compare_objects
|
||||
from
|
||||
sql_query (select_role_permissions, Void)
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
loop
|
||||
if attached sql_read_string (1) as l_permission then
|
||||
Result.force (l_permission)
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: roles and permissions
|
||||
|
||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||
@@ -553,18 +574,7 @@ feature -- Change: roles and permissions
|
||||
a_user_role.permissions as ic
|
||||
loop
|
||||
p := ic.item
|
||||
from
|
||||
l_found := False
|
||||
l_permissions.start
|
||||
until
|
||||
l_found or l_permissions.after
|
||||
loop
|
||||
if p.is_case_insensitive_equal (l_permissions.item) then
|
||||
l_found := True
|
||||
else
|
||||
l_permissions.forth
|
||||
end
|
||||
end
|
||||
l_found := across l_permissions as p_ic some p.is_case_insensitive_equal_general (p_ic.item) end
|
||||
if l_found then
|
||||
-- Already there, skip
|
||||
else
|
||||
@@ -915,6 +925,9 @@ feature {NONE} -- Sql Queries: USER ROLE
|
||||
select_role_permissions_by_role_id: STRING = "SELECT permission, module FROM role_permissions WHERE rid=:rid;"
|
||||
-- User role permissions for role id :rid;
|
||||
|
||||
select_role_permissions: STRING = "SELECT DISTINCT permission FROM role_permissions;"
|
||||
-- Used user role permissions
|
||||
|
||||
sql_delete_role_permissions_by_role_id: STRING = "DELETE FROM role_permissions WHERE rid=:rid;"
|
||||
|
||||
sql_delete_role_by_id: STRING = "DELETE FROM roles WHERE rid=:rid;"
|
||||
|
||||
@@ -32,6 +32,14 @@ feature -- Access
|
||||
dependencies: detachable LIST [TYPE [CMS_MODULE]]
|
||||
-- Optional dependencies.
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
require
|
||||
is_initialized: is_initialized
|
||||
do
|
||||
create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0)
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
|
||||
@@ -25,6 +25,7 @@ feature -- User
|
||||
|
||||
current_user (req: WSF_REQUEST): detachable CMS_USER
|
||||
-- Current user or Void in case of Guest user.
|
||||
-- note: if a CMS_RESPONSE is available, always prefer {CMS_RESPONSE}.user if relevant.
|
||||
note
|
||||
EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
|
||||
do
|
||||
@@ -70,4 +71,7 @@ feature -- Media Type
|
||||
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
|
||||
|
||||
@@ -194,9 +194,14 @@ feature -- Access: CMS
|
||||
values: CMS_VALUE_TABLE
|
||||
-- Associated values indexed by string name.
|
||||
|
||||
|
||||
feature -- User access
|
||||
|
||||
is_authenticated: BOOLEAN
|
||||
-- Is user authenticated?
|
||||
do
|
||||
Result := user /= Void
|
||||
end
|
||||
|
||||
user: detachable CMS_USER
|
||||
do
|
||||
Result := current_user (request)
|
||||
@@ -204,16 +209,28 @@ feature -- User access
|
||||
|
||||
feature -- Permission
|
||||
|
||||
has_permission_on_link (a_link: CMS_LINK): BOOLEAN
|
||||
-- Does current user has permission to access link `a_link'?
|
||||
do
|
||||
Result := True
|
||||
if
|
||||
attached {CMS_LOCAL_LINK} a_link as lnk and then
|
||||
attached lnk.permission_arguments as l_perms
|
||||
then
|
||||
Result := has_permissions (l_perms)
|
||||
end
|
||||
end
|
||||
|
||||
has_permission (a_permission: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Does current user has permission `a_permission' ?
|
||||
do
|
||||
Result := user_has_permission (current_user (request), a_permission)
|
||||
Result := user_has_permission (user, a_permission)
|
||||
end
|
||||
|
||||
has_permissions (a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN
|
||||
-- Does current user has any of the permissions `a_permission_list' ?
|
||||
do
|
||||
Result := user_has_permissions (current_user (request), a_permission_list)
|
||||
Result := user_has_permissions (user, a_permission_list)
|
||||
end
|
||||
|
||||
user_has_permission (a_user: detachable CMS_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN
|
||||
@@ -296,6 +313,12 @@ feature -- Element change
|
||||
main_content := s
|
||||
end
|
||||
|
||||
add_variable (a_element: ANY; a_key:READABLE_STRING_32)
|
||||
obsolete "Use `set_value' [Aug/2015]"
|
||||
do
|
||||
set_value (a_element, a_key)
|
||||
end
|
||||
|
||||
set_value (v: detachable ANY; k: READABLE_STRING_GENERAL)
|
||||
-- Set value `v' associated with name `k'.
|
||||
do
|
||||
@@ -859,15 +882,16 @@ feature -- Generation
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
local
|
||||
lnk: CMS_LINK
|
||||
l_menu_list_prepared: ARRAYED_LIST [CMS_LINK_COMPOSITE]
|
||||
do
|
||||
-- Menu
|
||||
create {CMS_LOCAL_LINK} lnk.make ("Home", "")
|
||||
lnk.set_weight (-10)
|
||||
add_to_primary_menu (lnk)
|
||||
invoke_menu_system_alter (menu_system)
|
||||
prepare_menu_system (menu_system)
|
||||
|
||||
-- Blocks
|
||||
create l_menu_list_prepared.make (0)
|
||||
get_blocks
|
||||
across
|
||||
regions as reg_ic
|
||||
@@ -876,11 +900,23 @@ feature -- Generation
|
||||
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)
|
||||
l_menu_list_prepared.force (l_menu_block.menu)
|
||||
prepare_links (l_menu_block.menu)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Prepare menu not in a block.
|
||||
across
|
||||
menu_system as ic
|
||||
loop
|
||||
if not l_menu_list_prepared.has (ic.item) then
|
||||
l_menu_list_prepared.force (ic.item)
|
||||
prepare_links (ic.item)
|
||||
end
|
||||
end
|
||||
l_menu_list_prepared.wipe_out -- Clear for memory purpose.
|
||||
|
||||
-- Sort items
|
||||
across menu_system as ic loop
|
||||
ic.item.sort
|
||||
@@ -951,7 +987,7 @@ feature -- Generation
|
||||
page.set_title (title)
|
||||
debug ("cms")
|
||||
if title = Void then
|
||||
page.set_title ("CMS::" + request.path_info) --| FIXME: probably, should be removed and handled by theme.
|
||||
page.set_title ({STRING_32} "CMS::" + request.path_info) --| FIXME: probably, should be removed and handled by theme.
|
||||
end
|
||||
end
|
||||
|
||||
@@ -988,54 +1024,19 @@ feature -- Generation
|
||||
do
|
||||
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
|
||||
get_local_link_active_status (lm)
|
||||
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)
|
||||
prepare_links (a_comp: CMS_LINK_COMPOSITE)
|
||||
-- Update the active status recursively on `a_comp'.
|
||||
local
|
||||
to_remove: ARRAYED_LIST [CMS_LINK]
|
||||
ln: CMS_LINK
|
||||
l_comp_link: detachable CMS_LOCAL_LINK
|
||||
do
|
||||
if attached {CMS_LOCAL_LINK} a_comp as lnk then
|
||||
l_comp_link := lnk
|
||||
get_local_link_active_status (lnk)
|
||||
end
|
||||
if attached a_comp.items as l_items then
|
||||
create to_remove.make (0)
|
||||
across
|
||||
l_items as ic
|
||||
loop
|
||||
@@ -1043,15 +1044,27 @@ feature -- Generation
|
||||
if attached {CMS_LOCAL_LINK} ln as l_local then
|
||||
get_local_link_active_status (l_local)
|
||||
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
|
||||
if l_comp_link /= Void then
|
||||
if ln.is_expanded or (not ln.is_expandable and ln.is_active) then
|
||||
l_comp_link.set_expanded (True)
|
||||
if ln.is_forbidden then
|
||||
to_remove.force (ln)
|
||||
else
|
||||
if
|
||||
(ln.is_expanded or ln.is_collapsed) and then
|
||||
attached {CMS_LINK_COMPOSITE} ln as l_comp
|
||||
then
|
||||
prepare_links (l_comp)
|
||||
end
|
||||
if l_comp_link /= Void then
|
||||
if ln.is_expanded or (not ln.is_expandable and ln.is_active) then
|
||||
l_comp_link.set_expanded (True)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
across
|
||||
to_remove as ic
|
||||
loop
|
||||
a_comp.remove (ic.item)
|
||||
end
|
||||
end
|
||||
if l_comp_link /= Void and then l_comp_link.is_active then
|
||||
l_comp_link.set_expanded (True)
|
||||
@@ -1077,25 +1090,7 @@ feature -- Generation
|
||||
l_is_active := qs.same_string (a_lnk.location)
|
||||
end
|
||||
a_lnk.set_is_active (l_is_active)
|
||||
end
|
||||
|
||||
feature -- Custom Variables
|
||||
|
||||
variables: detachable STRING_TABLE[ANY]
|
||||
-- Custom variables to feed the templates.
|
||||
|
||||
feature -- Element change: Add custom variables.
|
||||
|
||||
add_variable (a_element: ANY; a_key:READABLE_STRING_32)
|
||||
local
|
||||
l_variables: like variables
|
||||
do
|
||||
l_variables := variables
|
||||
if l_variables = Void then
|
||||
create l_variables.make (5)
|
||||
variables := l_variables
|
||||
end
|
||||
l_variables.force (a_element, a_key)
|
||||
a_lnk.set_is_forbidden (not has_permission_on_link (a_lnk))
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (absolute_url (request.path_info, Void), "request")
|
||||
page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request")
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.bad_request)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
@@ -35,4 +35,7 @@ feature -- Execution
|
||||
set_main_content ("<em>Bad request.</em>")
|
||||
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
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (absolute_url (request.path_info, Void), "request")
|
||||
page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request")
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.forbidden)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
@@ -34,5 +34,8 @@ feature -- Execution
|
||||
set_page_title ("Forbidden")
|
||||
set_main_content ("<em>Access denied for resource <strong>" + request.request_uri + "</strong>.</em>")
|
||||
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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (absolute_url (request.path_info, Void), "request")
|
||||
page.register_variable (absolute_url (location, Void), "request")
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
@@ -34,5 +34,8 @@ feature -- Execution
|
||||
set_page_title (Void)
|
||||
set_main_content ("<em>Internal Server Error</em>")
|
||||
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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (absolute_url (request.path_info, Void), "request")
|
||||
page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request")
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
@@ -34,5 +34,8 @@ feature -- Execution
|
||||
set_page_title ("Not Found")
|
||||
set_main_content ("<em>The requested page could not be found.</em>")
|
||||
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
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (absolute_url (request.path_info, Void), "request")
|
||||
page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request")
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.not_implemented)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
@@ -36,5 +36,8 @@ feature -- Execution
|
||||
set_main_content (request.percent_encoded_path_info + " is not implemented!")
|
||||
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
|
||||
|
||||
|
||||
@@ -7,24 +7,11 @@ class
|
||||
GENERIC_VIEW_CMS_RESPONSE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
custom_prepare
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
if attached variables as l_variables then
|
||||
across l_variables as c loop page.register_variable (c.item, c.key) end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
note
|
||||
description: "Summary description for {CMS_USER_API}."
|
||||
author: ""
|
||||
description: "API providing user related features."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
@@ -143,12 +142,52 @@ feature -- User roles.
|
||||
Result := storage.user_role_by_name (a_name)
|
||||
end
|
||||
|
||||
role_permissions: LIST [READABLE_STRING_8]
|
||||
-- Possible known permissions.
|
||||
local
|
||||
perm: READABLE_STRING_8
|
||||
do
|
||||
Result := storage.role_permissions
|
||||
across
|
||||
cms_api.enabled_modules as ic
|
||||
loop
|
||||
across
|
||||
ic.item.permissions as perms_ic
|
||||
loop
|
||||
perm := perms_ic.item
|
||||
if not Result.has (perm) then
|
||||
Result.force (perm)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
roles: LIST [CMS_USER_ROLE]
|
||||
-- List of possible roles.
|
||||
do
|
||||
Result := storage.user_roles
|
||||
end
|
||||
|
||||
effective_roles: LIST [CMS_USER_ROLE]
|
||||
-- List of possible roles, apart from anonymous and authenticated roles that are special.
|
||||
local
|
||||
l_roles: like roles
|
||||
r: CMS_USER_ROLE
|
||||
do
|
||||
l_roles := storage.user_roles
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (l_roles.count)
|
||||
across
|
||||
l_roles as ic
|
||||
loop
|
||||
r := ic.item
|
||||
if r.same_user_role (anonymous_user_role) or r.same_user_role (authenticated_user_role) then
|
||||
-- Ignore
|
||||
else
|
||||
Result.force (r)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
roles_count: INTEGER
|
||||
-- Number of roles
|
||||
do
|
||||
|
||||
@@ -266,19 +266,24 @@ feature -- Convertion
|
||||
pagination_links as ic
|
||||
loop
|
||||
lnk := ic.item
|
||||
if lnk.is_active then
|
||||
a_output.append ("<li class=%"active%">")
|
||||
elseif lnk.title.same_string (label_previous) then
|
||||
a_output.append ("<li class=%"previous%">")
|
||||
elseif lnk.title.same_string (label_next) then
|
||||
a_output.append ("<li class=%"next%">")
|
||||
else
|
||||
a_output.append ("<li>")
|
||||
if not lnk.is_forbidden then
|
||||
if lnk.is_active then
|
||||
a_output.append ("<li class=%"active%">")
|
||||
elseif lnk.title.same_string (label_previous) then
|
||||
a_output.append ("<li class=%"previous%">")
|
||||
elseif lnk.title.same_string (label_next) then
|
||||
a_output.append ("<li class=%"next%">")
|
||||
else
|
||||
a_output.append ("<li>")
|
||||
end
|
||||
a_output.append (a_response.link (lnk.title, lnk.location, Void))
|
||||
a_output.append ("</li>")
|
||||
end
|
||||
a_output.append (a_response.link (lnk.title, lnk.location, Void))
|
||||
a_output.append ("</li>")
|
||||
end
|
||||
a_output.append ("</ul>")
|
||||
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
|
||||
|
||||
@@ -148,46 +148,45 @@ feature {NONE} -- Implementation
|
||||
local
|
||||
cl: STRING
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Remove HTML from Eiffel")
|
||||
end
|
||||
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=%"")
|
||||
s.append (url (lnk.location, Void))
|
||||
s.append ("%">")
|
||||
s.append (html_encoded (lnk.title))
|
||||
s.append ("</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)
|
||||
if not lnk.is_forbidden then
|
||||
create cl.make_empty
|
||||
if lnk.is_active then
|
||||
cl.append ("active ")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
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=%"")
|
||||
s.append (url (lnk.location, Void))
|
||||
s.append ("%">")
|
||||
s.append (html_encoded (lnk.title))
|
||||
s.append ("</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
|
||||
s.append ("</li>")
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user