diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e index 475da6e..ddf16de 100644 --- a/src/hooks/cms_hook_core_manager.e +++ b/src/hooks/cms_hook_core_manager.e @@ -138,12 +138,16 @@ feature -- Hook: block invoke_block (a_response: CMS_RESPONSE) -- Invoke block hook for response `a_response' in order to get block from modules. local - bl: READABLE_STRING_8 + bl, l_alias: READABLE_STRING_8 bl_optional: BOOLEAN l_ok: BOOLEAN l_block_cache: detachable TUPLE [block: CMS_CACHE_BLOCK; region: READABLE_STRING_8; expired: BOOLEAN] + l_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] --| block_id => [alias_ids..] + l_origin_block: detachable CMS_BLOCK do if attached subscribers ({CMS_HOOK_BLOCK}) as lst then + l_alias_table := a_response.block_alias_table + across lst as c loop @@ -162,6 +166,7 @@ feature -- Hook: block else l_ok := True end + if l_ok then l_block_cache := a_response.block_cache (bl) if l_block_cache /= Void and then not l_block_cache.expired then @@ -170,6 +175,30 @@ feature -- Hook: block h.get_block_view (bl, a_response) end end + if + l_alias_table /= Void and then + attached l_alias_table.item (bl) as l_aliases + then + across + l_aliases as aliases_ic + loop + l_alias := aliases_ic.item + l_origin_block := a_response.blocks.item (bl) + if l_origin_block = Void then + h.get_block_view (bl, a_response) + l_origin_block := a_response.blocks.item (bl) + if l_origin_block /= Void then + -- Previously, it was not included. + -- Computed only to include alias + -- then remove `l_origin_block'. + a_response.remove_block (l_origin_block) + end + end + if l_origin_block /= Void then + a_response.add_block (create {CMS_ALIAS_BLOCK}.make_with_block (l_alias, l_origin_block), Void) + end + end + end end end end diff --git a/src/kernel/content/cms_alias_block.e b/src/kernel/content/cms_alias_block.e new file mode 100644 index 0000000..60cc9fa --- /dev/null +++ b/src/kernel/content/cms_alias_block.e @@ -0,0 +1,59 @@ +note + description: "[ + Block being an alias of other block. + + Mainly to avoid multiple region for a block content. + ]" + date: "$Date$" + revision: "$Revision$" + +class + CMS_ALIAS_BLOCK + +inherit + CMS_BLOCK + +create + make_with_block + +feature {NONE} -- Initialization + + make_with_block (a_name: READABLE_STRING_8; a_block: CMS_BLOCK) + do + name := a_name + origin := a_block + title := a_block.title + end + +feature -- Access + + origin: CMS_BLOCK + + name: READABLE_STRING_8 + +feature -- Status report + + is_empty: BOOLEAN + -- + do + Result := origin.is_empty + end + + is_raw: BOOLEAN + -- + do + Result := origin.is_raw + end + +feature -- Conversion + + to_html (a_theme: CMS_THEME): STRING_8 + -- HTML representation of Current block. + do + Result := origin.to_html (a_theme) + 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 diff --git a/src/kernel/content/cms_block.e b/src/kernel/content/cms_block.e index 544da41..74568fa 100644 --- a/src/kernel/content/cms_block.e +++ b/src/kernel/content/cms_block.e @@ -6,6 +6,11 @@ deferred class CMS_BLOCK inherit + CMS_BLOCK_SETUP + undefine + is_equal + end + COMPARABLE DEBUG_OUTPUT @@ -20,18 +25,9 @@ feature -- Access deferred end - title: detachable READABLE_STRING_32 - -- Optional title. - deferred - end - html_options: detachable CMS_HTML_OPTIONS -- Optional addition html options. - weight: INTEGER - -- Weight used to order blocks. - -- Default: 0; - feature -- Status report is_empty: BOOLEAN @@ -48,9 +44,6 @@ feature -- Status report deferred end - conditions: detachable LIST [CMS_BLOCK_CONDITION] - -- Optional block condition to be enabled. - feature -- Comparison is_less alias "<" (other: like Current): BOOLEAN @@ -87,25 +80,6 @@ feature -- Element change opts.remove_css_class (a_class) end - add_condition (a_condition: CMS_BLOCK_CONDITION) - -- Add condition `a_condition'. - local - l_conditions: like conditions - do - l_conditions := conditions - if l_conditions = Void then - create {ARRAYED_LIST [CMS_BLOCK_CONDITION]} l_conditions.make (1) - conditions := l_conditions - end - l_conditions.force (a_condition) - end - - set_weight (w: like weight) - -- Set `weight' to `w'. - do - weight := w - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_block_setup.e b/src/kernel/content/cms_block_setup.e new file mode 100644 index 0000000..d30116e --- /dev/null +++ b/src/kernel/content/cms_block_setup.e @@ -0,0 +1,55 @@ +note + description: "Settings for CMS_BLOCK, that could be set and overwritten via CMS configuration." + date: "$Date$" + revision: "$Revision$" + +class + CMS_BLOCK_SETUP + +feature -- Access + + title: detachable READABLE_STRING_32 + -- Optional title. + + weight: INTEGER + -- Weight used to order blocks. + -- Default: 0. + + conditions: detachable LIST [CMS_BLOCK_CONDITION] + -- Optional block condition to be enabled. + +feature -- Element change + + set_title (a_title: detachable READABLE_STRING_GENERAL) + -- Set `title' with `a_title'. + do + if a_title = Void then + title := Void + else + title := a_title.as_string_32 + end + end + + set_weight (w: like weight) + -- Set `weight' to `w'. + do + weight := w + end + + add_condition (a_condition: CMS_BLOCK_CONDITION) + -- Add condition `a_condition'. + local + l_conditions: like conditions + do + l_conditions := conditions + if l_conditions = Void then + create {ARRAYED_LIST [CMS_BLOCK_CONDITION]} l_conditions.make (1) + conditions := l_conditions + end + l_conditions.force (a_condition) + 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 diff --git a/src/kernel/content/cms_cache_block.e b/src/kernel/content/cms_cache_block.e index 29e885c..56d8aed 100644 --- a/src/kernel/content/cms_cache_block.e +++ b/src/kernel/content/cms_cache_block.e @@ -32,9 +32,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - cache: CMS_CACHE [READABLE_STRING_8] -- Cache content. @@ -65,12 +62,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_content_block.e b/src/kernel/content/cms_content_block.e index d45f89c..ffc975e 100644 --- a/src/kernel/content/cms_content_block.e +++ b/src/kernel/content/cms_content_block.e @@ -39,9 +39,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - content: READABLE_STRING_8 format: detachable CONTENT_FORMAT @@ -74,12 +71,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - feature -- Conversion to_html (a_theme: CMS_THEME): STRING_8 diff --git a/src/kernel/content/cms_menu_block.e b/src/kernel/content/cms_menu_block.e index 8e060d8..f0efa41 100644 --- a/src/kernel/content/cms_menu_block.e +++ b/src/kernel/content/cms_menu_block.e @@ -27,8 +27,6 @@ feature -- Access name: READABLE_STRING_8 - title: detachable READABLE_STRING_32 - feature -- Status report is_empty: BOOLEAN @@ -53,12 +51,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - set_is_horizontal (b: BOOLEAN) -- Set `is_horizontal' to `b'. do diff --git a/src/kernel/content/cms_smarty_template_block.e b/src/kernel/content/cms_smarty_template_block.e index bfff2ab..7e53d9b 100644 --- a/src/kernel/content/cms_smarty_template_block.e +++ b/src/kernel/content/cms_smarty_template_block.e @@ -58,9 +58,6 @@ feature -- Access name: READABLE_STRING_8 -- - title: detachable READABLE_STRING_32 - -- - location: PATH -- Location of template file. @@ -94,12 +91,6 @@ feature -- Element change name := n end - set_title (a_title: like title) - -- Set `title' to `a_title'. - do - title := a_title - end - set_value (v: detachable ANY; k: READABLE_STRING_GENERAL) -- Associate value `v' with key `k'. do diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 6adc338..2ff4f46 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -401,6 +401,7 @@ feature -- Blocks initialization fixme ("let the user choose ...") end create regions.make_caseless (5) + create blocks.make (10) create l_table.make_caseless (10) l_table["top"] := block_region_preference ("top", "top") @@ -434,10 +435,19 @@ feature -- Block management then a_block.set_weight (w.to_integer) end + if + attached setup.text_item ("blocks." + a_block.name + ".title") as l_title + then + if l_title.same_string ("") then + a_block.set_title (Void) + else + a_block.set_title (l_title) + end + end end block_conditions (a_block_id: READABLE_STRING_8): detachable ARRAYED_LIST [CMS_BLOCK_EXPRESSION_CONDITION] - -- Condition associated with `a_block_id' in configuration, if any. + -- Condition associated with `a_block_id' in configuration, if any. do if attached setup.text_item ("blocks." + a_block_id + ".condition") as s then create Result.make (1) @@ -446,11 +456,11 @@ feature -- Block management if attached setup.text_list_item ("blocks." + a_block_id + ".conditions") as lst then if Result = Void then create Result.make (lst.count) - across - lst as ic - loop - Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (ic.item)) - end + end + across + lst as ic + loop + Result.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (ic.item)) end end end @@ -517,11 +527,60 @@ feature -- Block management end end +feature {CMS_HOOK_CORE_MANAGER} -- Block management: internal + + internal_block_alias_table: like block_alias_table + -- Internal memory cache for `block_alias_table'. + + block_alias_table: detachable STRING_TABLE [LIST [READABLE_STRING_8]] + -- Table of included block aliases, if any. + -- note: { block_id => [ alias-names ..] } + local + k,v: READABLE_STRING_GENERAL + l_block_id, l_alias_id: READABLE_STRING_8 + lst: detachable LIST [READABLE_STRING_8] + do + Result := internal_block_alias_table + if + Result = Void and then + attached setup.text_table_item ("blocks.&aliases") as tb + then + create Result.make (tb.count) + across + tb as ic + loop + k := ic.key + v := ic.item + if v.is_valid_as_string_8 then + l_block_id := v.to_string_8 + if k.is_valid_as_string_8 then + l_alias_id := k.to_string_8 + if is_block_included (l_alias_id, False) then + lst := Result.item (l_block_id) + if lst = Void then + create {ARRAYED_LIST [READABLE_STRING_8]} lst.make (1) + end + lst.force (l_alias_id) + Result.force (lst, l_block_id) + end + else + check valid_alias_id: False end + end + else + check valid_block_id: False end + end + end + end + end + feature -- Blocks regions regions: STRING_TABLE [CMS_BLOCK_REGION] -- Layout regions, that contains blocks. + blocks: STRING_TABLE [CMS_BLOCK] + -- Blocks indexed by their block id. + block_region_settings: STRING_TABLE [STRING] block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION @@ -551,6 +610,34 @@ feature -- Blocks regions end end +feature {NONE} -- Blocks + + put_core_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN; a_alias_table: like block_alias_table) + -- Add block `b' to associated region or `a_default_region' if provided + -- and check optional associated condition. + -- If no condition then use `is_block_included_by_default' to + -- decide if block is included or not. + local + l_region: detachable like block_region + do + if is_block_included (b.name, is_block_included_by_default) then + l_region := block_region (b, a_default_region) + l_region.extend (b) + blocks.force (b, b.name) + end + -- Included alias block ids. + if + a_alias_table /= Void and then + attached a_alias_table.item (b.name) as l_aliases + then + across + l_aliases as ic + loop + add_block (create {CMS_ALIAS_BLOCK}.make_with_block (ic.item, b), a_default_region) + end + end + end + feature -- Blocks put_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8; is_block_included_by_default: BOOLEAN) @@ -564,6 +651,7 @@ feature -- Blocks if is_block_included (b.name, is_block_included_by_default) then l_region := block_region (b, a_default_region) l_region.extend (b) + blocks.force (b, b.name) end end @@ -575,37 +663,37 @@ feature -- Blocks do l_region := block_region (b, a_default_region) l_region.extend (b) + blocks.force (b, b.name) + end + + remove_block (b: CMS_BLOCK) + -- Remove block `b' from associated region. + local + l_region: detachable like block_region + l_found: BOOLEAN + do + across + regions as reg_ic + until + l_found + loop + l_region := reg_ic.item + l_found := l_region.blocks.has (b) + if l_found then + l_region.remove (b) + end + end + blocks.remove (b.name) end get_blocks -- Get block from CMS core, and from modules. local l_region: CMS_BLOCK_REGION + b: CMS_BLOCK do - debug ("refactor_fixme") - fixme ("find a way to have this in configuration or database, and allow different order") - end - put_block (top_header_block, "top", True) - put_block (header_block, "header", True) - if attached message_block as m then - put_block (m, "content", True) - end - if attached primary_tabs_block as m then - put_block (m, "content", True) - end - add_block (content_block, "content") -- Can not be disabled! - - if attached management_menu_block as l_block then - put_block (l_block, "sidebar_first", True) - end - if attached navigation_menu_block as l_block then - put_block (l_block, "sidebar_first", True) - end - if attached user_menu_block as l_block then - put_block (l_block, "sidebar_second", True) - end - - hooks.invoke_block (Current) + get_core_blocks + get_module_blocks across regions as reg_ic @@ -620,10 +708,48 @@ feature -- Blocks end debug ("cms") - put_block (create {CMS_CONTENT_BLOCK}.make ("made_with", Void, "Made with EWF", Void), "footer", True) + create {CMS_CONTENT_BLOCK} b.make ("made_with", Void, "Made with EWF", Void) + b.set_weight (99) + put_block (b, "footer", True) end end + get_core_blocks + -- Get blocks provided by the CMS core. + local + l_alias_table: like block_alias_table + do + -- Get included aliased blocks. + l_alias_table := block_alias_table + + put_core_block (top_header_block, "top", True, l_alias_table) + put_core_block (header_block, "header", True, l_alias_table) + if attached message_block as m then + put_core_block (m, "content", True, l_alias_table) + end + if attached primary_tabs_block as m then + put_core_block (m, "content", True, l_alias_table) + end + add_block (content_block, "content") -- Can not be disabled! + + if attached management_menu_block as l_block then + put_core_block (l_block, "sidebar_first", True, l_alias_table) + end + if attached navigation_menu_block as l_block then + put_core_block (l_block, "sidebar_first", True, l_alias_table) + end + if attached user_menu_block as l_block then + put_core_block (l_block, "sidebar_second", True, l_alias_table) + end + end + + get_module_blocks + -- Get blocks provided by modules. + do + -- Get block from modules, and related alias. + hooks.invoke_block (Current) + end + primary_menu_block: detachable CMS_MENU_BLOCK do if attached primary_menu as m and then not m.is_empty then