+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