diff --git a/modules/blog/cms_blog_module.e b/modules/blog/cms_blog_module.e
index ec38c1e..31786ca 100644
--- a/modules/blog/cms_blog_module.e
+++ b/modules/blog/cms_blog_module.e
@@ -65,7 +65,7 @@ feature {CMS_API} -- Module Initialization
loop
ct.extend_format (ic.item)
end
- l_node_api.add_content_type (ct)
+ l_node_api.add_node_type (ct)
l_node_api.add_content_type_webform_manager (create {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}.make (ct))
-- Add support for CMS_BLOG, which requires a storage extension to store the optional "tags" value
diff --git a/modules/node/cms_node_api.e b/modules/node/cms_node_api.e
index c77e926..02c0714 100644
--- a/modules/node/cms_node_api.e
+++ b/modules/node/cms_node_api.e
@@ -40,8 +40,7 @@ feature {NONE} -- Initialization
local
ct: CMS_PAGE_NODE_TYPE
do
- -- Initialize content types.
- create content_types.make (1)
+ -- Initialize node content types.
create content_type_webform_managers.make (1)
create ct
--| For now, add all available formats to content type `ct'.
@@ -50,7 +49,7 @@ feature {NONE} -- Initialization
loop
ct.extend_format (ic.item)
end
- add_content_type (ct)
+ add_node_type (ct)
add_content_type_webform_manager (create {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}.make (ct))
end
@@ -60,15 +59,18 @@ feature {CMS_MODULE} -- Access nodes storage.
feature -- Content type
- content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
- -- Available content types
+ add_node_type (a_type: CMS_NODE_TYPE [CMS_NODE])
+ -- Register node content type `a_type'.
+ do
+ cms_api.add_content_type (a_type)
+ end
node_types: ARRAYED_LIST [attached like node_type]
-- Node content types.
do
- create Result.make (content_types.count)
+ create Result.make (cms_api.content_types.count)
across
- content_types as ic
+ cms_api.content_types as ic
loop
if attached {like node_type} ic.item as l_node_type then
Result.extend (l_node_type)
@@ -76,32 +78,11 @@ feature -- Content type
end
end
- add_content_type (a_type: CMS_CONTENT_TYPE)
- -- Register content type `a_type'.
- do
- content_types.force (a_type)
- end
-
- content_type (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE
- -- Content type named `a_named' if any.
- do
- across
- content_types as ic
- until
- Result /= Void
- loop
- Result := ic.item
- if not a_name.is_case_insensitive_equal (Result.name) then
- Result := Void
- end
- end
- end
-
node_type (a_name: READABLE_STRING_GENERAL): detachable CMS_NODE_TYPE [CMS_NODE]
-- Content type named `a_named' if any.
do
across
- content_types as ic
+ cms_api.content_types as ic
until
Result /= Void
loop
diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e
index 0ea6f2d..f67a475 100644
--- a/modules/node/cms_node_module.e
+++ b/modules/node/cms_node_module.e
@@ -158,7 +158,7 @@ feature -- Access
if attached node_api as l_node_api then
across
- l_node_api.content_types as ic
+ l_node_api.node_types as ic
loop
l_type_name := ic.item.name
if not l_type_name.is_whitespace then
@@ -285,7 +285,7 @@ feature -- Hooks
create perms.make (2)
perms.force ("create any node")
across
- l_node_api.content_types as ic
+ l_node_api.node_types as ic
loop
perms.force ("create " + ic.item.name)
end
@@ -300,7 +300,7 @@ feature -- Hooks
do
if
attached node_api as l_node_api and then
- attached l_node_api.content_types as l_types and then
+ attached l_node_api.node_types as l_types and then
not l_types.is_empty
then
create lst.make (l_types.count)
diff --git a/modules/node/content/cms_node.e b/modules/node/content/cms_node.e
index 41ab55d..f7a755c 100644
--- a/modules/node/content/cms_node.e
+++ b/modules/node/content/cms_node.e
@@ -10,7 +10,11 @@ deferred class
CMS_NODE
inherit
- DEBUG_OUTPUT
+ CMS_CONTENT
+ redefine
+ debug_output
+ end
+
REFACTORING_HELPER
feature{NONE} -- Initialization
@@ -67,12 +71,6 @@ feature -- Access
-- Revision value.
--| Note: for now version is not supported.
- content_type: READABLE_STRING_8
- -- Associated content type name.
- -- Page, Article, Blog, News, etc.
- deferred
- end
-
feature -- Status reports
status: INTEGER
@@ -113,12 +111,6 @@ feature -- Access
deferred
end
- format: detachable READABLE_STRING_8
- -- Format associated with `content' and `summary'.
- -- For example: text, mediawiki, html, etc
- deferred
- end
-
feature -- Access: date
modification_date: DATE_TIME
@@ -155,12 +147,6 @@ feature -- status report
valid_result: Result implies a_node.id = id
end
- is_typed_as (a_content_type: READABLE_STRING_GENERAL): BOOLEAN
- -- Is current node of type `a_content_type' ?
- do
- Result := a_content_type.is_case_insensitive_equal (content_type)
- end
-
feature -- Access: menu
link: detachable CMS_LOCAL_LINK
@@ -174,13 +160,7 @@ feature -- Status report
create Result.make_from_string_general ("#")
Result.append_integer_64 (id)
Result.append_character (' ')
- Result.append_character ('<')
- Result.append_string_general (content_type)
- Result.append_character ('>')
- Result.append_character (' ')
- Result.append_character ('%"')
- Result.append (title)
- Result.append_character ('%"')
+ Result.append (Precursor)
end
feature -- Element change
diff --git a/modules/node/handler/nodes_handler.e b/modules/node/handler/nodes_handler.e
index 55d9be5..b129341 100644
--- a/modules/node/handler/nodes_handler.e
+++ b/modules/node/handler/nodes_handler.e
@@ -96,7 +96,7 @@ feature -- HTTP Methods
s.append (" (trashed)")
end
debug
- if attached node_api.content_type (n.content_type) as ct then
+ if attached node_api.node_type (n.content_type) as ct then
s.append ("")
s.append (html_encoded (ct.title))
s.append ("")
diff --git a/modules/node/persistence/cms_node_storage_sql.e b/modules/node/persistence/cms_node_storage_sql.e
index 897d5e5..3047652 100644
--- a/modules/node/persistence/cms_node_storage_sql.e
+++ b/modules/node/persistence/cms_node_storage_sql.e
@@ -383,7 +383,6 @@ feature -- Change: Node
local
l_parameters: STRING_TABLE [ANY]
l_time: DATE_TIME
- l_sql_delete_node_aliases: STRING
do
sql_begin_transaction
create l_time.make_now_utc
diff --git a/modules/node/persistence/cms_node_storage_sql_page_extension.e b/modules/node/persistence/cms_node_storage_sql_page_extension.e
index abfe110..cd0dd5e 100644
--- a/modules/node/persistence/cms_node_storage_sql_page_extension.e
+++ b/modules/node/persistence/cms_node_storage_sql_page_extension.e
@@ -101,7 +101,7 @@ feature -- Persistence
l_parent_id /= a_node.id and then
attached node_storage.node_by_id (l_parent_id) as l_parent
then
- if attached {CMS_PAGE_NODE_TYPE} node_api.content_type (l_parent.content_type) as l_parent_ct then
+ if attached {CMS_PAGE_NODE_TYPE} node_api.node_type (l_parent.content_type) as l_parent_ct then
ct := l_parent_ct
else
create ct
diff --git a/modules/taxonomy/cms_taxonomy_api.e b/modules/taxonomy/cms_taxonomy_api.e
index f0b3ea7..051239b 100644
--- a/modules/taxonomy/cms_taxonomy_api.e
+++ b/modules/taxonomy/cms_taxonomy_api.e
@@ -103,7 +103,7 @@ feature -- Access node
Result := taxonomy_storage.terms (a_vocab, a_limit, a_offset)
end
- term_by_id (a_tid: INTEGER): detachable CMS_TERM
+ term_by_id (a_tid: INTEGER_64): detachable CMS_TERM
do
Result := taxonomy_storage.term_by_id (a_tid)
end
@@ -114,6 +114,14 @@ feature -- Access node
Result := taxonomy_storage.term_by_text (a_term_text, a_vocabulary)
end
+ entities_associated_with_term (a_term: CMS_TERM): detachable LIST [TUPLE [entity: READABLE_STRING_32; type: detachable READABLE_STRING_32]]
+ -- Entities and related typename associated with `a_term'.
+ require
+ a_term_exists: a_term.has_id
+ do
+ Result := taxonomy_storage.entities_associated_with_term (a_term)
+ end
+
feature -- Write
save_vocabulary (a_voc: CMS_VOCABULARY)
diff --git a/modules/taxonomy/cms_taxonomy_module.e b/modules/taxonomy/cms_taxonomy_module.e
index 77a1249..4e0091b 100644
--- a/modules/taxonomy/cms_taxonomy_module.e
+++ b/modules/taxonomy/cms_taxonomy_module.e
@@ -35,7 +35,7 @@ feature {NONE} -- Initialization
version := "1.0"
description := "Taxonomy solution"
package := "core"
--- add_dependency ({CMS_NODE_MODULE})
+-- put_dependency ({CMS_NODE_MODULE}, False)
end
feature -- Access
@@ -120,19 +120,9 @@ feature -- Access: router
-- Configure router mapping for web interface.
local
l_taxonomy_handler: TAXONOMY_HANDLER
- l_uri_mapping: WSF_URI_MAPPING
do
create l_taxonomy_handler.make (a_api, a_taxonomy_api)
- -- Let the class BLOG_HANDLER handle the requests on "/taxonomys"
- create l_uri_mapping.make_trailing_slash_ignored ("/taxonomy", l_taxonomy_handler)
- a_router.map (l_uri_mapping, a_router.methods_get)
-
- -- We can add a page number after /taxonomys/ to get older posts
- a_router.handle ("/taxonomy/{vocabulary}", l_taxonomy_handler, a_router.methods_get)
-
- -- If a user id is given route with taxonomy user handler
- --| FIXME: maybe /user/{user}/taxonomys/ would be better.
- a_router.handle ("/taxonomy/{vocabulary}/{termid}", l_taxonomy_handler, a_router.methods_get)
+ a_router.handle ("/taxonomy/term/{termid}", l_taxonomy_handler, a_router.methods_get)
end
feature -- Hooks
diff --git a/modules/taxonomy/handler/taxonomy_handler.e b/modules/taxonomy/handler/taxonomy_handler.e
index bef7d11..81b93e3 100644
--- a/modules/taxonomy/handler/taxonomy_handler.e
+++ b/modules/taxonomy/handler/taxonomy_handler.e
@@ -1,9 +1,7 @@
note
description: "[
Request handler related to
- /taxonomy
- /taxonomy/{vocabulary}
- /taxonomy/{vocabulary}/{term}
+ /taxonomy/term/{termid}
]"
date: "$Date$"
revision: "$revision$"
@@ -69,13 +67,68 @@ feature -- HTTP Methods
--
local
l_page: CMS_RESPONSE
+ tid: INTEGER_64
+ l_typename: detachable READABLE_STRING_8
+ l_entity: detachable READABLE_STRING_32
+ s: STRING
do
- -- Read page number from path parameter.
+ if
+ attached {WSF_STRING} req.path_parameter ("termid") as p_termid and then
+ p_termid.is_integer
+ then
+ tid := p_termid.value.to_integer_64
+ end
- -- Responding with `main_content_html (l_page)'.
- create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
- l_page.set_main_content ("Not Yet Implemented -- In Progress")
- l_page.execute
+ if tid > 0 then
+ if attached taxonomy_api.term_by_id (tid) as t then
+ -- Responding with `main_content_html (l_page)'.
+ create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
+ create s.make_empty
+ l_page.set_page_title ("Entities associated with term %"" + l_page.html_encoded (t.text) + "%":")
+
+ if
+ attached taxonomy_api.entities_associated_with_term (t) as l_entity_type_lst and then
+ not l_entity_type_lst.is_empty
+ then
+ s.append ("")
+ across
+ l_entity_type_lst as ic
+ loop
+ -- FIXME: for now basic implementation .. to be replaced by specific hook !
+ if attached ic.item.entity as e and then e.is_valid_as_string_8 then
+ l_entity := e.to_string_8
+ if attached ic.item.type as l_type and then l_type.is_valid_as_string_8 then
+ l_typename := l_type.to_string_8
+ else
+ l_typename := Void
+ end
+ if l_typename /= Void then
+ s.append ("- ")
+ if
+ l_typename.is_case_insensitive_equal_general ("page")
+ or l_typename.is_case_insensitive_equal_general ("blog")
+ then
+ s.append (l_page.link ({STRING_32} "" + l_typename + "/" + l_entity, "node/" + l_entity.to_string_8, Void))
+ end
+ s.append ("
%N")
+ end
+ end
+ end
+ s.append ("
%N")
+ else
+ s.append ("No entity found.")
+ end
+ l_page.set_main_content (s)
+ else
+ -- Responding with `main_content_html (l_page)'.
+ create {NOT_FOUND_ERROR_CMS_RESPONSE} l_page.make (req, res, api)
+ end
+ l_page.execute
+ else
+ -- Responding with `main_content_html (l_page)'.
+ create {BAD_REQUEST_ERROR_CMS_RESPONSE} l_page.make (req, res, api)
+ l_page.execute
+ end
end
end
diff --git a/modules/taxonomy/persistence/cms_taxonomy_storage_i.e b/modules/taxonomy/persistence/cms_taxonomy_storage_i.e
index 559d0d7..b7fa34d 100644
--- a/modules/taxonomy/persistence/cms_taxonomy_storage_i.e
+++ b/modules/taxonomy/persistence/cms_taxonomy_storage_i.e
@@ -80,6 +80,13 @@ feature -- Access
deferred
end
+ entities_associated_with_term (a_term: CMS_TERM): detachable LIST [TUPLE [entity: READABLE_STRING_32; type: detachable READABLE_STRING_32]]
+ -- Entities and related typename associated with `a_term'.
+ require
+ a_term_exists: a_term.has_id
+ deferred
+ end
+
feature -- Store
save_vocabulary (a_voc: CMS_VOCABULARY)
diff --git a/modules/taxonomy/persistence/cms_taxonomy_storage_null.e b/modules/taxonomy/persistence/cms_taxonomy_storage_null.e
index bd8f05d..0e9def6 100644
--- a/modules/taxonomy/persistence/cms_taxonomy_storage_null.e
+++ b/modules/taxonomy/persistence/cms_taxonomy_storage_null.e
@@ -78,6 +78,11 @@ feature -- Access
do
end
+ entities_associated_with_term (a_term: CMS_TERM): detachable LIST [TUPLE [entity: READABLE_STRING_32; type: detachable READABLE_STRING_32]]
+ -- Entities and related typename associated with `a_term'.
+ do
+ end
+
feature -- Store
save_vocabulary (a_voc: CMS_VOCABULARY)
diff --git a/modules/taxonomy/persistence/cms_taxonomy_storage_sql.e b/modules/taxonomy/persistence/cms_taxonomy_storage_sql.e
index 5ed17dc..c71e73f 100644
--- a/modules/taxonomy/persistence/cms_taxonomy_storage_sql.e
+++ b/modules/taxonomy/persistence/cms_taxonomy_storage_sql.e
@@ -198,6 +198,38 @@ feature -- Access
end
end
+ entities_associated_with_term (a_term: CMS_TERM): detachable LIST [TUPLE [entity: READABLE_STRING_32; type: detachable READABLE_STRING_32]]
+ -- Entities and related typename associated with `a_term'.
+ local
+ l_parameters: STRING_TABLE [detachable ANY]
+ l_typename: detachable READABLE_STRING_32
+ do
+ error_handler.reset
+
+ create l_parameters.make (3)
+ l_parameters.put (a_term.id, "tid")
+ sql_query (sql_select_entity_and_type_by_term, l_parameters)
+
+ if not has_error then
+ create {ARRAYED_LIST [TUPLE [entity: READABLE_STRING_32; type: detachable READABLE_STRING_32]]} Result.make (0)
+ from
+ sql_start
+ until
+ sql_after or has_error
+ loop
+ if attached sql_read_string_32 (1) as l_entity then
+ l_typename := sql_read_string_32 (2)
+ if l_typename /= Void and then l_typename.is_whitespace then
+ l_typename := Void
+ end
+ Result.force ([l_entity, l_typename])
+ end
+ sql_forth
+ end
+ end
+ sql_finalize
+ end
+
feature -- Store
save_vocabulary (voc: CMS_VOCABULARY)
@@ -477,6 +509,12 @@ feature {NONE} -- Queries
SELECT tid FROM taxonomy_index WHERE type=:type AND entity=:entity;
]"
+ sql_select_entity_and_type_by_term: STRING = "[
+ SELECT entity, type FROM taxonomy_index WHERE tid=:tid AND entity > 0
+ ORDER BY type ASC, entity ASC
+ ;
+ ]"
+
sql_select_vocabulary_terms_of_entity: STRING = "[
SELECT taxonomy_index.tid
FROM taxonomy_index INNER JOIN taxonomy_hierarchy ON taxonomy_index.tid=taxonomy_hierarchy.tid
diff --git a/modules/taxonomy/taxonomy-safe.ecf b/modules/taxonomy/taxonomy-safe.ecf
index e4813e9..e3578e2 100644
--- a/modules/taxonomy/taxonomy-safe.ecf
+++ b/modules/taxonomy/taxonomy-safe.ecf
@@ -16,6 +16,7 @@
+
diff --git a/src/kernel/content/cms_content_block.e b/src/kernel/content/cms_content_block.e
index ffc975e..8eb62d0 100644
--- a/src/kernel/content/cms_content_block.e
+++ b/src/kernel/content/cms_content_block.e
@@ -83,6 +83,7 @@ feature -- Conversion
Result := content
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)"
diff --git a/src/service/cms_api.e b/src/service/cms_api.e
index 8d1b450..4ef772c 100644
--- a/src/service/cms_api.e
+++ b/src/service/cms_api.e
@@ -43,6 +43,8 @@ feature {NONE} -- Initialize
do
-- Initialize formats.
initialize_formats
+ -- Initialize contents.
+ initialize_content_types
-- Initialize storage.
if attached setup.storage (error_handler) as l_storage then
@@ -88,6 +90,12 @@ feature {NONE} -- Initialize
end
end
+ initialize_content_types
+ -- Initialize content types.
+ do
+ create content_types.make (1)
+ end
+
initialize_formats
-- Initialize content formats.
local
@@ -156,6 +164,32 @@ feature -- Access
storage: CMS_STORAGE
-- Default persistence storage.
+feature -- Content
+
+ content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
+ -- Available content types
+
+ add_content_type (a_type: CMS_CONTENT_TYPE)
+ -- Register content type `a_type'.
+ do
+ content_types.force (a_type)
+ end
+
+ content_type (a_name: READABLE_STRING_GENERAL): detachable CMS_CONTENT_TYPE
+ -- Content type named `a_named' if any.
+ do
+ across
+ content_types as ic
+ until
+ Result /= Void
+ loop
+ Result := ic.item
+ if not a_name.is_case_insensitive_equal (Result.name) then
+ Result := Void
+ end
+ end
+ end
+
feature -- Formats
formats: CMS_FORMATS
diff --git a/src/service/content/cms_content.e b/src/service/content/cms_content.e
new file mode 100644
index 0000000..e6c9444
--- /dev/null
+++ b/src/service/content/cms_content.e
@@ -0,0 +1,66 @@
+note
+ description: "[
+ Abstract of entity managed by CMS.
+ ]"
+ date: "$Date$"
+ revision: "$Revision$"
+
+deferred class
+ CMS_CONTENT
+
+inherit
+ DEBUG_OUTPUT
+
+feature -- Access
+
+ title: detachable READABLE_STRING_32
+ -- Title associated with Current content.
+ deferred
+ end
+
+ content_type: READABLE_STRING_8
+ -- Associated content type name.
+ -- Page, Article, Blog, News, etc.
+ deferred
+ end
+
+ format: detachable READABLE_STRING_8
+ -- Format associated with `content' and `summary'.
+ -- For example: text, mediawiki, html, etc
+ deferred
+ end
+
+ link: detachable CMS_LOCAL_LINK
+ -- Associated menu link.
+ deferred
+ end
+
+feature -- Status report
+
+ is_typed_as (a_content_type: READABLE_STRING_GENERAL): BOOLEAN
+ -- Is current node of type `a_content_type' ?
+ do
+ Result := a_content_type.is_case_insensitive_equal (content_type)
+ end
+
+feature -- Status report
+
+ debug_output: STRING_32
+ --
+ do
+ create Result.make_empty
+ Result.append_character ('<')
+ Result.append_string_general (content_type)
+ Result.append_character ('>')
+ if attached title as l_title then
+ Result.append_character (' ')
+ Result.append_character ('%"')
+ Result.append (l_title)
+ Result.append_character ('%"')
+ 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
diff --git a/modules/node/cms_content_type.e b/src/service/content/cms_content_type.e
similarity index 100%
rename from modules/node/cms_content_type.e
rename to src/service/content/cms_content_type.e
diff --git a/src/service/content/cms_partial_content.e b/src/service/content/cms_partial_content.e
new file mode 100644
index 0000000..8b114b0
--- /dev/null
+++ b/src/service/content/cms_partial_content.e
@@ -0,0 +1,73 @@
+note
+ description: "[
+ Instance of CMS_CONTENT representing the minimal information
+ for a CMS_CONTENT.
+ ]"
+ date: "$Date$"
+ revision: "$Revision$"
+
+class
+ CMS_PARTIAL_CONTENT
+
+inherit
+ CMS_CONTENT
+
+create
+ make_empty
+
+feature {NONE} -- Initialization
+
+ make_empty (a_content_type: READABLE_STRING_8)
+ require
+ type_not_blank: not a_content_type.is_whitespace
+ do
+ content_type := a_content_type
+ end
+
+feature -- Access
+
+ title: detachable READABLE_STRING_32
+ -- Title associated with Current content.
+
+ content_type: READABLE_STRING_8
+ -- Associated content type name.
+ -- Page, Article, Blog, News, etc.
+
+ format: detachable READABLE_STRING_8
+ -- Format associated with `content' and `summary'.
+ -- For example: text, mediawiki, html, etc
+
+ link: detachable CMS_LOCAL_LINK
+ -- Associated menu link.
+
+feature -- Element change
+
+ set_title (a_title: detachable READABLE_STRING_GENERAL)
+ do
+ if a_title = Void then
+ title := Void
+ else
+ create {STRING_32} title.make_from_string_general (a_title)
+ end
+ end
+
+ set_format (a_format: like format)
+ -- Assign `format' with `a_format'.
+ do
+ format := a_format
+ ensure
+ format_assigned: format = a_format
+ end
+
+ set_link (a_link: like link)
+ -- Assign `link' with `a_link'.
+ do
+ link := a_link
+ ensure
+ link_assigned: link = a_link
+ 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