diff --git a/examples/demo/demo-safe.ecf b/examples/demo/demo-safe.ecf index 25d0e56..a781967 100644 --- a/examples/demo/demo-safe.ecf +++ b/examples/demo/demo-safe.ecf @@ -25,6 +25,7 @@ + diff --git a/examples/demo/install_modules.bat b/examples/demo/install_modules.bat index a21ac49..591cac0 100644 --- a/examples/demo/install_modules.bat +++ b/examples/demo/install_modules.bat @@ -18,3 +18,4 @@ set ROC_CMS_DIR=%~dp0 %ROC_CMD% install --module ..\..\modules\session_auth --dir %ROC_CMS_DIR% %ROC_CMD% install --module ..\..\modules\taxonomy --dir %ROC_CMS_DIR% %ROC_CMD% install --module ..\..\modules\files --dir %ROC_CMS_DIR% +%ROC_CMD% install --module ..\..\modules\custom_block --dir %ROC_CMS_DIR% diff --git a/examples/demo/site/modules/custom_block/config/custom_block.json b/examples/demo/site/modules/custom_block/config/custom_block.json new file mode 100644 index 0000000..f18b9ac --- /dev/null +++ b/examples/demo/site/modules/custom_block/config/custom_block.json @@ -0,0 +1,10 @@ +{ + "blocks": { + "test": { + "title": "Custom block test", + "region": "footer", + "weight": 100, + "conditions": ["path:demo/*"] + } + } +} diff --git a/examples/demo/site/modules/custom_block/templates/block_test.tpl b/examples/demo/site/modules/custom_block/templates/block_test.tpl new file mode 100644 index 0000000..842e4cd --- /dev/null +++ b/examples/demo/site/modules/custom_block/templates/block_test.tpl @@ -0,0 +1,3 @@ +
+This is a nice custom block test for site {$sitename/}. +
diff --git a/examples/demo/src/demo_cms_execution.e b/examples/demo/src/demo_cms_execution.e index d4d1384..7cd58a1 100644 --- a/examples/demo/src/demo_cms_execution.e +++ b/examples/demo/src/demo_cms_execution.e @@ -77,6 +77,7 @@ feature -- CMS modules -- Miscellanious a_setup.register_module (create {GOOGLE_CUSTOM_SEARCH_MODULE}.make) + a_setup.register_module (create {CMS_CUSTOM_BLOCK_MODULE}.make) a_setup.register_module (create {CMS_DEBUG_MODULE}.make) a_setup.register_module (create {CMS_DEMO_MODULE}.make) diff --git a/library/configuration/src/config_reader.e b/library/configuration/src/config_reader.e index 2698b35..3988763 100644 --- a/library/configuration/src/config_reader.e +++ b/library/configuration/src/config_reader.e @@ -34,7 +34,7 @@ feature -- Query end resolved_text_list_item (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32] - -- List of String item associated with key `k', + -- List of String items associated with key `k', -- and expanded values to resolved variables ${varname}. do if attached text_list_item (k) as lst then @@ -50,7 +50,7 @@ feature -- Query end resolved_text_table_item (k: READABLE_STRING_GENERAL): detachable STRING_TABLE [READABLE_STRING_32] - -- Table of String item associated with key `k', + -- Table of String items associated with key `k', -- and expanded values to resolved variables ${varname}. do if attached text_table_item (k) as tb then @@ -71,12 +71,17 @@ feature -- Query end text_list_item (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32] - -- List of String item associated with key `k'. + -- List of String items associated with key `k'. deferred end text_table_item (k: READABLE_STRING_GENERAL): detachable STRING_TABLE [READABLE_STRING_32] - -- Table of String item associated with key `k'. + -- Table of String items associated with key `k'. + deferred + end + + table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32] + -- Keys of table associated with key `k'. deferred end diff --git a/library/configuration/src/ini_config.e b/library/configuration/src/ini_config.e index 0456e43..1e8c077 100644 --- a/library/configuration/src/ini_config.e +++ b/library/configuration/src/ini_config.e @@ -163,6 +163,20 @@ feature -- Access: Config Reader end end + table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32] + -- + do + if attached {STRING_TABLE [like item]} item (k) as l_list then + create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (l_list.count) + Result.compare_objects + across + l_list as ic + loop + Result.force (ic.key.as_string_32) + end + end + end + integer_item (k: READABLE_STRING_GENERAL): INTEGER -- Integer item associated with key `k'. do @@ -442,12 +456,12 @@ feature {NONE} -- Implementation j := k.index_of (']', i + 1) if j = i + 1 then -- ends_with "[]" k.keep_head (i - 1) - if + if a_section_prefix /= Void and then attached {LIST [STRING_8]} items.item (a_section_prefix + {STRING_32} "." + k) as l_list then lst := l_list - elseif + elseif attached last_section_name as l_section_prefix and then attached {LIST [STRING_8]} items.item (l_section_prefix + {STRING_32} "." + k) as l_list then @@ -466,12 +480,12 @@ feature {NONE} -- Implementation sk.left_adjust sk.right_adjust k.keep_head (i - 1) - if + if a_section_prefix /= Void and then attached {STRING_TABLE [STRING_8]} items.item (a_section_prefix + {STRING_32} "." + k) as l_table then tb := l_table - elseif + elseif attached last_section_name as l_section_prefix and then attached {STRING_TABLE [STRING_8]} items.item (l_section_prefix + {STRING_32} "." + k) as l_table then @@ -522,7 +536,7 @@ feature {NONE} -- Implementation invariant note - copyright: "2011-2015, Jocelyn Fiat, Eiffel Software and others" + copyright: "2011-2016, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/library/configuration/src/json_config.e b/library/configuration/src/json_config.e index 54fe3d3..3962a08 100644 --- a/library/configuration/src/json_config.e +++ b/library/configuration/src/json_config.e @@ -105,6 +105,20 @@ feature -- Access: Config Reader end end end + + table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32] + -- + do + if attached {JSON_OBJECT} item (k) as obj then + create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (obj.count) + Result.compare_objects + across + obj as ic + loop + Result.force (ic.key.item) + end + end + end integer_item (k: READABLE_STRING_GENERAL): INTEGER -- Integer item associated with key `k'. diff --git a/library/configuration/tests/test_config_reader_set.e b/library/configuration/tests/test_config_reader_set.e index 2f90530..fc16ca9 100644 --- a/library/configuration/tests/test_config_reader_set.e +++ b/library/configuration/tests/test_config_reader_set.e @@ -75,13 +75,21 @@ feature -- Test lst.has ("a") and lst.has ("b") and lst.has ("c") and lst.has ("1") and lst.has ("2") and lst.has ("3") ) ) - + assert ("has_item (table)", cfg.has_item ("table")) assert ("item (table)", attached cfg.text_table_item ("table") as tb and then ( - tb.item ("a") ~ {STRING_32} "1" and - tb.item ("b") ~ {STRING_32} "2" and - tb.item ("c") ~ {STRING_32} "3" and - tb.item ("d") ~ {STRING_32} "test" + tb.item ("a") ~ {STRING_32} "1" and + tb.item ("b") ~ {STRING_32} "2" and + tb.item ("c") ~ {STRING_32} "3" and + tb.item ("d") ~ {STRING_32} "test" + ) + ) + + assert ("keys of (table)", attached cfg.table_keys ("table") as tb and then ( + tb.i_th (1) ~ {STRING_32} "a" and + tb.i_th (2) ~ {STRING_32} "b" and + tb.i_th (3) ~ {STRING_32} "c" and + tb.i_th (4) ~ {STRING_32} "d" ) ) @@ -198,13 +206,21 @@ feature -- Test lst.has ("a") and lst.has ("b") and lst.has ("c") and lst.has ("1") and lst.has ("2") and lst.has ("3") ) ) - + assert ("has_item (table)", cfg.has_item ("table")) assert ("item (table)", attached cfg.text_table_item ("table") as tb and then ( - tb.item ("a") ~ {STRING_32} "1" and - tb.item ("b") ~ {STRING_32} "2" and - tb.item ("c") ~ {STRING_32} "3" and - tb.item ("d") ~ {STRING_32} "test" + tb.item ("a") ~ {STRING_32} "1" and + tb.item ("b") ~ {STRING_32} "2" and + tb.item ("c") ~ {STRING_32} "3" and + tb.item ("d") ~ {STRING_32} "test" + ) + ) + + assert ("keys of (table)", attached cfg.table_keys ("table") as tb and then ( + tb.i_th (1) ~ {STRING_32} "a" and + tb.i_th (2) ~ {STRING_32} "b" and + tb.i_th (3) ~ {STRING_32} "c" and + tb.i_th (4) ~ {STRING_32} "d" ) ) diff --git a/modules/custom_block/cms_custom_block_module.e b/modules/custom_block/cms_custom_block_module.e new file mode 100644 index 0000000..eb3a634 --- /dev/null +++ b/modules/custom_block/cms_custom_block_module.e @@ -0,0 +1,165 @@ +note + description: "[ + Module that provide custom block factory. + ]" + author: "$Author: jfiat $" + date: "$Date: 2016-01-08 22:43:12 +0100 (ven., 08 janv. 2016) $" + revision: "$Revision: 98369 $" + +class + CMS_CUSTOM_BLOCK_MODULE + +inherit + CMS_MODULE + rename + module_api as custom_block_api + redefine + initialize, + setup_hooks, + custom_block_api + end + + CMS_HOOK_RESPONSE_BLOCK + + CMS_HOOK_BLOCK_HELPER + + CMS_HOOK_AUTO_REGISTER + + SHARED_EXECUTION_ENVIRONMENT + export + {NONE} all + end + + REFACTORING_HELPER + +create + make + +feature {NONE} -- Initialization + + make + -- Create current module + do + version := "1.0" + description := "Custom Block" + package := "layout" + end + +feature -- Access + + name: STRING = "custom_block" + -- + +feature {CMS_API} -- Module Initialization + + initialize (api: CMS_API) + -- Initialize Current module with `api'. + do + create custom_block_api.make (api) + Precursor (api) + end + + custom_block_api: detachable CMS_MODULE_API + -- . + +feature -- Router + + setup_router (a_router: WSF_ROUTER; a_api: CMS_API) + -- Router configuration. + do + end + +feature -- Hooks configuration + + setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER) + -- Module hooks configuration. + do + auto_subscribe_to_hooks (a_hooks) + a_hooks.subscribe_to_block_hook (Current) + end + +feature -- Hooks + + block_identifiers (a_response: detachable CMS_RESPONSE): detachable ARRAYED_LIST [READABLE_STRING_8] + -- + local + api: CMS_API + l_name: READABLE_STRING_32 + l_block_id: READABLE_STRING_8 + l_conds: detachable ARRAYED_LIST [CMS_BLOCK_CONDITION] + do + if attached custom_block_api as l_mod_api then + api := l_mod_api.cms_api + if + attached api.module_configuration (Current, name) as cfg and then + attached cfg.table_keys ("blocks") as lst + then + create Result.make (0) + across + lst as ic + loop + l_name := ic.item + if l_name.is_valid_as_string_8 then + l_block_id := l_name.to_string_8 + if a_response /= Void then + if attached cfg.text_list_item ("blocks." + l_block_id + ".conditions") as l_cond_expressions then + if l_conds = Void then + create l_conds.make (l_cond_expressions.count) + end + across + l_cond_expressions as exp_ic + loop + l_conds.force (create {CMS_BLOCK_EXPRESSION_CONDITION}.make (exp_ic.item)) + end + end + if l_conds = Void or else l_conds.is_empty then + Result.force ("?" + l_block_id) + elseif are_conditions_satisfied (l_conds, a_response) then + Result.force (l_block_id) + end + else + Result.force ("?" + l_block_id) + end + end + end + end + end + end + + are_conditions_satisfied (a_conditions: LIST [CMS_BLOCK_CONDITION]; a_response: CMS_RESPONSE): BOOLEAN + -- Are `a_conditions' satisfied for `a_response'? + do + Result := across a_conditions as ic some ic.item.satisfied_for_response (a_response) end + end + + get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + local + l_region: detachable READABLE_STRING_8 + l_cond: CMS_BLOCK_EXPRESSION_CONDITION + do + if attached smarty_template_block (Current, a_block_id, a_response.api) as bk then + if attached a_response.api.module_configuration (Current, name) as cfg then + if + attached cfg.text_item ("blocks." + a_block_id + ".region") as s and then + s.is_valid_as_string_8 + then + l_region := s.to_string_8 + end + bk.set_weight (cfg.integer_item ("blocks." + a_block_id + ".weight")) + bk.set_title (cfg.text_item ("blocks." + a_block_id + ".title")) + if attached cfg.text_list_item ("blocks." + a_block_id + ".conditions") as l_cond_exp_list then + across + l_cond_exp_list as ic + loop + create l_cond.make (ic.item) + bk.add_condition (l_cond) + end + end + end + a_response.add_block (bk, l_region) + else + a_response.add_debug_message ("Missing template for custom block %"" + a_block_id + "%"!") + end + end + +end diff --git a/modules/custom_block/custom_block-safe.ecf b/modules/custom_block/custom_block-safe.ecf new file mode 100644 index 0000000..1ca8072 --- /dev/null +++ b/modules/custom_block/custom_block-safe.ecf @@ -0,0 +1,21 @@ + + + + + + /.svn$ + /CVS$ + /EIFGENs$ + + + diff --git a/modules/custom_block/custom_block.ecf b/modules/custom_block/custom_block.ecf new file mode 100644 index 0000000..880a872 --- /dev/null +++ b/modules/custom_block/custom_block.ecf @@ -0,0 +1,22 @@ + + + + + + /.svn$ + /CVS$ + /EIFGENs$ + + + + + + + + + + + + + diff --git a/modules/custom_block/site/config/custom_block.json.example b/modules/custom_block/site/config/custom_block.json.example new file mode 100644 index 0000000..f18b9ac --- /dev/null +++ b/modules/custom_block/site/config/custom_block.json.example @@ -0,0 +1,10 @@ +{ + "blocks": { + "test": { + "title": "Custom block test", + "region": "footer", + "weight": 100, + "conditions": ["path:demo/*"] + } + } +} diff --git a/modules/custom_block/site/templates/block_test.tpl.example b/modules/custom_block/site/templates/block_test.tpl.example new file mode 100644 index 0000000..842e4cd --- /dev/null +++ b/modules/custom_block/site/templates/block_test.tpl.example @@ -0,0 +1,3 @@ +
+This is a nice custom block test for site {$sitename/}. +
diff --git a/src/hooks/cms_hook_block.e b/src/hooks/cms_hook_block.e index 864b190..3b4946d 100644 --- a/src/hooks/cms_hook_block.e +++ b/src/hooks/cms_hook_block.e @@ -1,6 +1,6 @@ note description: "[ - Hook providing a way to alter a block. + Hook providing a way to provide blocks. ]" date: "$Date: 2014-11-19 20:00:19 +0100 (mer., 19 nov. 2014) $" revision: "$Revision: 96123 $" @@ -13,13 +13,21 @@ inherit feature -- Hook - block_list: ITERABLE [like {CMS_BLOCK}.name] + block_list: detachable ITERABLE [like {CMS_BLOCK}.name] -- List of block names, managed by current object. - -- If prefixed by "?", condition will be check + -- If prefixed by "?", condition will be checked -- to determine if it should be displayed (and computed) or not. deferred end + block_identifiers (a_response: detachable CMS_RESPONSE): detachable ITERABLE [like {CMS_BLOCK}.name] + -- List of block names, managed by current object, in the context of `a_response' if set. + -- If prefixed by "?", condition will be checked + -- to determine if it should be displayed (and computed) or not. + do + Result := block_list + end + get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) -- Get block object identified by `a_block_id' and associate with `a_response'. deferred diff --git a/src/hooks/cms_hook_core_manager.e b/src/hooks/cms_hook_core_manager.e index eaa2dc1..ed38cb7 100644 --- a/src/hooks/cms_hook_core_manager.e +++ b/src/hooks/cms_hook_core_manager.e @@ -150,9 +150,12 @@ feature -- Hook: block across lst as c loop - if attached {CMS_HOOK_BLOCK} c.item as h then + if + attached {CMS_HOOK_BLOCK} c.item as h and then + attached h.block_identifiers (a_response) as l_names + then across - h.block_list as blst + l_names as blst loop bl := blst.item bl_optional := bl.count > 0 and bl[1] = '?' @@ -252,6 +255,6 @@ feature -- Hook: export end note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2016, 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/hooks/cms_hook_response_block.e b/src/hooks/cms_hook_response_block.e new file mode 100644 index 0000000..efb46ba --- /dev/null +++ b/src/hooks/cms_hook_response_block.e @@ -0,0 +1,45 @@ +note + description: "[ + Hook providing a way to provide blocks, + within the context of a response. + ]" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_HOOK_RESPONSE_BLOCK + +inherit + CMS_HOOK_BLOCK + rename + block_identifiers as old_block_identifiers + redefine + old_block_identifiers + end + +feature -- Hook + + frozen block_list: detachable ITERABLE [like {CMS_BLOCK}.name] + -- List of block names, managed by current object. + -- If prefixed by "?", condition will be checked + -- to determine if it should be displayed (and computed) or not. + do + Result := block_identifiers (Void) + end + + frozen old_block_identifiers (a_response: detachable CMS_RESPONSE): detachable ITERABLE [like {CMS_BLOCK}.name] + do + Result := block_identifiers (a_response) + end + + block_identifiers (a_response: detachable CMS_RESPONSE): detachable ITERABLE [like {CMS_BLOCK}.name] + -- List of block names, managed by current object, in the context of `a_response' if set. + -- If prefixed by "?", condition will be checked + -- to determine if it should be displayed (and computed) or not. + deferred + end + +note + copyright: "2011-2016, 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/block/condition/cms_block_expression_condition.e b/src/kernel/content/block/condition/cms_block_expression_condition.e index 0691f84..9ccd5cf 100644 --- a/src/kernel/content/block/condition/cms_block_expression_condition.e +++ b/src/kernel/content/block/condition/cms_block_expression_condition.e @@ -15,7 +15,7 @@ create feature {NONE} -- Initialization - make (a_exp: READABLE_STRING_8) + make (a_exp: READABLE_STRING_GENERAL) do expression := a_exp end @@ -30,18 +30,18 @@ feature -- Access description: STRING_32 do create Result.make_from_string_general ("Expression: %"") - Result.append_string_general (expression) + Result.append_string_general (expression.as_string_32) Result.append_character ('%"') end - expression: STRING + expression: READABLE_STRING_GENERAL feature -- Evaluation satisfied_for_response (res: CMS_RESPONSE): BOOLEAN local exp: like expression - l_path: READABLE_STRING_8 + l_path: READABLE_STRING_GENERAL kmp: KMP_WILD do exp := expression @@ -61,12 +61,12 @@ feature -- Evaluation Result := kmp.pattern_matches end else - Result := res.location.same_string (l_path) + Result := l_path.same_string (res.location) end end end note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2016, 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/service/response/cms_response.e b/src/service/response/cms_response.e index a191d55..0eeaed4 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -994,7 +994,7 @@ feature -- Message add_debug_message (a_msg: READABLE_STRING_8) do - if api.is_debug_enabled then + if api.is_debug then add_message (a_msg, "debug") end end