Added notion of CMS_CONTENT as ancestor of CMS_NODE.

Moved CMS_CONTENT_TYPE to core library.
Added basic and limited taxonomy query /taxonomy/term/{termid} .
This commit is contained in:
2015-12-03 23:01:31 +01:00
parent a5c117e46e
commit ecbcb6a5cb
19 changed files with 319 additions and 83 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -96,7 +96,7 @@ feature -- HTTP Methods
s.append (" <em>(trashed)</em>")
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 ("<span class=%"description%">")
s.append (html_encoded (ct.title))
s.append ("</span>")

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
-- <Precursor>
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 ("<ul class=%"taxonomy-entities%">")
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 ("<li class=%""+ l_typename +"%">")
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 ("</li>%N")
end
end
end
s.append ("</ul>%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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -16,6 +16,7 @@
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>

View File

@@ -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)"

View File

@@ -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

View File

@@ -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
-- <Precursor>
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

View File

@@ -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