Implemented taxonomy administration pages

- create term, vocabulary, add or remove term from vocabularies, ...
Fixed content editing related to taxonomy  (especially with multiple terms vs tags).
Fixed various SQL storage issue related to taxonomy and vocabularies.
Added CMS_RESPONSE.wsf_theme as helper.
This commit is contained in:
2015-12-10 11:21:20 +01:00
parent e3ae564746
commit ce8de442e9
30 changed files with 1302 additions and 247 deletions

View File

@@ -19,3 +19,8 @@ ul.taxonomy li:hover {
border-bottom: solid 1px #66f;
background-color: #ddf;
}
table.taxonomy td {
border: solid 1px #ccc;
padding: 2px;
}

View File

@@ -19,3 +19,9 @@ ul.taxonomy {
}
}
}
table.taxonomy {
td {
border: solid 1px #ccc;
padding: 2px;
}
}

View File

@@ -91,13 +91,10 @@ ul.horizontal li {
padding: 5px 2px 5px 2px;
}
ul.taxonomy-entities {
list-style-type: none;
padding: 0;
table.with_border thead td {
font-weight: bold;
}
ul.taxonomy-entities li {
padding: 0;
margin-top: 5px;
margin-bottom: 10px;
border-top: dotted 1px #ccc;
table.with_border td {
border: solid 1px #ccc;
padding: 2px 5px 2px 5px;
}

View File

@@ -96,13 +96,12 @@ ul.horizontal {
padding: 5px 2px 5px 2px;
}
ul.taxonomy-entities {
list-style-type: none;
padding: 0;
li {
padding: 0;
margin-top: 5px;
margin-bottom: 10px;
border-top: dotted 1px #ccc;
table.with_border {
thead td {
font-weight: bold;
}
td {
border: solid 1px #ccc;
padding: 2px 5px 2px 5px;
}
}

View File

@@ -44,7 +44,7 @@ feature -- Execution
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
f := clear_cache_web_form (l_response)
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
f.append_to_html (l_response.wsf_theme, s)
l_response.set_main_content (s)
l_response.execute
end
@@ -70,7 +70,7 @@ feature -- Execution
end
end
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
f.append_to_html (l_response.wsf_theme, s)
l_response.set_main_content (s)
l_response.execute
end

View File

@@ -44,7 +44,7 @@ feature -- Execution
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
f := exportation_web_form (l_response)
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
f.append_to_html (l_response.wsf_theme, s)
l_response.set_main_content (s)
l_response.execute
end
@@ -85,7 +85,7 @@ feature -- Execution
end
end
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
f.append_to_html (l_response.wsf_theme, s)
l_response.set_main_content (s)
l_response.execute
end

View File

@@ -88,7 +88,7 @@ feature -- Execution
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
f := modules_collection_web_form (r)
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), s)
f.append_to_html (r.wsf_theme, s)
r.set_page_title ("Modules")
r.set_main_content (s)
r.execute
@@ -133,7 +133,7 @@ feature -- Execution
then
r.add_error_message ("Error occurred.")
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), s)
f.append_to_html (r.wsf_theme, s)
r.set_page_title ("Modules")
r.set_main_content (s)
else

View File

@@ -8,30 +8,10 @@ class
inherit
CMS_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Process
process

View File

@@ -8,32 +8,12 @@ class
inherit
CMS_RESPONSE
redefine
make,
initialize
end
CMS_SHARED_SORTING_UTILITIES
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Query
role_id_path_parameter (req: WSF_REQUEST): INTEGER_64

View File

@@ -8,31 +8,10 @@ class
inherit
CMS_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api;)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Query
role_id_path_parameter (req: WSF_REQUEST): INTEGER_64

View File

@@ -7,32 +7,11 @@ class
CMS_USER_FORM_RESPONSE
inherit
CMS_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Query
user_id_path_parameter (req: WSF_REQUEST): INTEGER_64

View File

@@ -8,31 +8,10 @@ class
inherit
CMS_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api;)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Query
user_id_path_parameter (req: WSF_REQUEST): INTEGER_64

View File

@@ -100,6 +100,7 @@ feature -- Forms ...
populate_form_with_taxonomy (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
local
ti: detachable WSF_FORM_TEXT_INPUT
th: WSF_FORM_HIDDEN_INPUT
w_set: WSF_FORM_FIELD_SET
w_select: WSF_FORM_SELECT
w_opt: WSF_FORM_SELECT_OPTION
@@ -126,6 +127,9 @@ feature -- Forms ...
l_vocs as vocs_ic
loop
voc := vocs_ic.item
create th.make_with_text ({STRING_32} "taxonomy_vocabularies[" + voc.id.out + "]", voc.name)
w_set.extend (th)
l_terms := Void
if a_node /= Void and then a_node.has_id then
l_terms := l_taxonomy_api.terms_of_entity (a_node.content_type, a_node.id.out, voc)
@@ -139,7 +143,7 @@ feature -- Forms ...
if voc.is_tags then
w_voc_set.set_legend (response.translation (voc.name, Void))
create ti.make ({STRING_32} "taxonomy_terms[" + voc.name + "]")
create ti.make ({STRING_32} "taxonomy_" + voc.id.out)
w_voc_set.extend (ti)
if voc.is_term_required then
ti.enable_required
@@ -186,7 +190,8 @@ feature -- Forms ...
voc as voc_terms_ic
loop
t := voc_terms_ic.item
create w_cb.make_with_value ({STRING_32} "taxonomy_terms[" + voc.name + "]", t.text)
create w_cb.make_with_value ({STRING_32} "taxonomy_" + voc.id.out + "[]", t.text)
w_cb.set_title (t.text)
w_voc_set.extend (w_cb)
if l_terms /= Void and then across l_terms as ic some ic.item.text.same_string (t.text) end then
w_cb.set_checked (True)
@@ -196,7 +201,7 @@ feature -- Forms ...
end
end
else
create w_select.make ({STRING_32} "taxonomy_terms[" + voc.name + "]")
create w_select.make ({STRING_32} "taxonomy_" + voc.id.out)
w_voc_set.extend (w_select)
if attached voc.description as l_desc then
@@ -248,68 +253,81 @@ feature -- Forms ...
l_text: READABLE_STRING_GENERAL
l_found: BOOLEAN
t: detachable CMS_TERM
vid: INTEGER_64
do
if
a_node /= Void and then a_node.has_id and then
attached fd.table_item ("taxonomy_terms") as fd_terms
attached fd.table_item ("taxonomy_vocabularies") as fd_vocs
then
across
fd_terms.values as ic
loop
if attached {WSF_STRING} ic.item as l_string then
l_voc_name := ic.key
l_new_terms := a_taxonomy_api.splitted_string (l_string.value, ',')
if attached a_vocs.item_by_name (l_voc_name) as voc then
if a_response.has_permissions (<<{STRING_32} "update any taxonomy", {STRING_32} "update " + content_type.name + " taxonomy">>) then
create l_terms_to_remove.make (0)
if attached a_taxonomy_api.terms_of_entity (content_type.name, a_node.id.out, voc) as l_existing_terms then
across
l_existing_terms as t_ic
if a_response.has_permissions (<<{STRING_32} "update any taxonomy", {STRING_32} "update " + content_type.name + " taxonomy">>) then
across
fd_vocs.values as ic
loop
vid := ic.key.to_integer_64
l_voc_name := ic.item.string_representation
if attached a_vocs.item_by_id (vid) as voc then
if attached fd.string_item ("taxonomy_" + vid.out) as l_string then
l_new_terms := a_taxonomy_api.splitted_string (l_string, ',')
elseif attached fd.table_item ("taxonomy_" + vid.out) as fd_terms then
create {ARRAYED_LIST [READABLE_STRING_32]} l_new_terms.make (fd_terms.count)
across
fd_terms as t_ic
loop
l_new_terms.force (t_ic.item.string_representation)
end
else
create {ARRAYED_LIST [READABLE_STRING_32]} l_new_terms.make (0)
end
create l_terms_to_remove.make (0)
if attached a_taxonomy_api.terms_of_entity (content_type.name, a_node.id.out, voc) as l_existing_terms then
across
l_existing_terms as t_ic
loop
l_text := t_ic.item.text
from
l_found := False
l_new_terms.start
until
l_new_terms.after
loop
l_text := t_ic.item.text
from
l_found := False
l_new_terms.start
until
l_new_terms.after
loop
if l_new_terms.item.same_string_general (l_text) then
-- Already associated with term `t_ic.text'.
l_found := True
l_new_terms.remove
else
l_new_terms.forth
end
end
if not l_found then
-- Remove term
l_terms_to_remove.force (t_ic.item)
if l_new_terms.item.same_string_general (l_text) then
-- Already associated with term `t_ic.text'.
l_found := True
l_new_terms.remove
else
l_new_terms.forth
end
end
across
l_terms_to_remove as t_ic
loop
a_taxonomy_api.unassociate_term_from_entity (t_ic.item, content_type.name, a_node.id.out)
if not l_found then
-- Remove term
l_terms_to_remove.force (t_ic.item)
end
end
across
l_new_terms as t_ic
l_terms_to_remove as t_ic
loop
t := a_taxonomy_api.term_by_text (t_ic.item, voc)
if
t = Void and voc.is_tags
then
-- Create new term!
create t.make (t_ic.item)
a_taxonomy_api.save_term (t, voc)
if a_taxonomy_api.has_error then
t := Void
end
end
if t /= Void then
a_taxonomy_api.associate_term_with_entity (t, content_type.name, a_node.id.out)
a_taxonomy_api.unassociate_term_from_entity (t_ic.item, content_type.name, a_node.id.out)
end
end
across
l_new_terms as t_ic
loop
t := a_taxonomy_api.term_by_text (t_ic.item, voc)
if
t = Void and voc.is_tags
then
-- Create new term!
create t.make (t_ic.item)
a_taxonomy_api.save_term (t, voc)
if a_taxonomy_api.has_error then
t := Void
end
end
if t /= Void then
a_taxonomy_api.associate_term_with_entity (t, content_type.name, a_node.id.out)
end
end
end
end

View File

@@ -7,30 +7,10 @@ class
inherit
NODE_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api; a_node_api: like node_api)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api, a_node_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Execution
process

View File

@@ -8,30 +8,10 @@ class
inherit
NODE_RESPONSE
redefine
make,
initialize
end
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api; a_node_api: like node_api)
do
create {WSF_NULL_THEME} wsf_theme.make
Precursor (req, res, a_api, a_node_api)
end
initialize
do
Precursor
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
end
wsf_theme: WSF_THEME
feature -- Access
node: detachable CMS_NODE

View File

@@ -284,7 +284,7 @@ feature -- Handler
create l_submit.make_with_text ("op", "Filter")
l_form.extend (l_submit)
l_form.extend_html_text ("<br/>")
l_form.append_to_html (create {CMS_TO_WSF_THEME}.make (r, r.theme), l_content)
l_form.append_to_html (r.wsf_theme, l_content)
end
l_changes.reverse_sort

View File

@@ -52,7 +52,7 @@ feature -- Access node
Result := taxonomy_storage.vocabularies (a_limit, a_offset)
end
vocabulary (a_id: INTEGER): detachable CMS_VOCABULARY
vocabulary (a_id: INTEGER_64): detachable CMS_VOCABULARY
-- Vocabulary associated with id `a_id'.
require
valid_id: a_id > 0
@@ -66,6 +66,27 @@ feature -- Access node
Result := taxonomy_storage.vocabularies_for_type (a_type_name)
end
types_associated_with_vocabulary (a_vocab: CMS_VOCABULARY): detachable LIST [READABLE_STRING_32]
-- Type names associated with `a_vocab'.
do
Result := taxonomy_storage.types_associated_with_vocabulary (a_vocab)
end
vocabularies_for_term (a_term: CMS_TERM): detachable CMS_VOCABULARY_COLLECTION
-- Vocabularies including `a_term'.
do
Result := taxonomy_storage.vocabularies_for_term (a_term)
end
is_term_inside_vocabulary (a_term: CMS_TERM; a_vocab: CMS_VOCABULARY): BOOLEAN
-- Is `a_term' inside `a_vocab' ?
require
valid_term: a_term.has_id
valid_vocabulary: a_vocab.has_id
do
Result := taxonomy_storage.is_term_inside_vocabulary (a_term, a_vocab)
end
fill_vocabularies_with_terms (a_vocab: CMS_VOCABULARY)
-- Fill `a_vocab' with associated terms.
do
@@ -125,19 +146,39 @@ feature -- Access node
feature -- Write
save_vocabulary (a_voc: CMS_VOCABULARY)
-- Insert or update vocabulary `a_voc'
-- and also save {CMS_VOCABULARY}.terms if `a_with_terms' is True.
do
reset_error
taxonomy_storage.save_vocabulary (a_voc)
taxonomy_storage.save_vocabulary (a_voc, False)
error_handler.append (taxonomy_storage.error_handler)
end
save_term (a_term: CMS_TERM; voc: CMS_VOCABULARY)
save_vocabulary_and_terms (a_voc: CMS_VOCABULARY)
-- Insert or update vocabulary `a_voc'
-- and also save {CMS_VOCABULARY}.terms.
do
reset_error
taxonomy_storage.save_vocabulary (a_voc, True)
error_handler.append (taxonomy_storage.error_handler)
end
save_term (a_term: CMS_TERM; voc: detachable CMS_VOCABULARY)
-- Save `a_term' inside `voc' if set.
do
reset_error
taxonomy_storage.save_term (a_term, voc)
error_handler.append (taxonomy_storage.error_handler)
end
remove_term_from_vocabulary (t: CMS_TERM; voc: CMS_VOCABULARY)
-- Remove term `t' from vocabulary `voc'.
do
reset_error
taxonomy_storage.remove_term_from_vocabulary (t, voc)
error_handler.append (taxonomy_storage.error_handler)
end
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
-- Associate term `a_term' with `(a_type_name, a_entity)'.
do

View File

@@ -109,6 +109,7 @@ feature -- Access: router
do
if attached taxonomy_api as l_taxonomy_api then
configure_web (a_api, l_taxonomy_api, a_router)
configure_web_amin (a_api, l_taxonomy_api, a_router)
else
-- Issue with api/dependencies,
-- thus Current module should not be used!
@@ -120,9 +121,48 @@ feature -- Access: router
-- Configure router mapping for web interface.
local
l_taxonomy_handler: TAXONOMY_HANDLER
l_voc_handler: TAXONOMY_VOCABULARY_HANDLER
do
create l_taxonomy_handler.make (a_api, a_taxonomy_api)
a_router.handle ("/taxonomy/term/{termid}", l_taxonomy_handler, a_router.methods_get)
create l_voc_handler.make (a_api, a_taxonomy_api)
a_router.handle ("/taxonomy/vocabulary/", l_voc_handler, a_router.methods_get)
a_router.handle ("/taxonomy/vocabulary/{vocid}", l_voc_handler, a_router.methods_get)
end
configure_web_amin (a_api: CMS_API; a_taxonomy_api: CMS_TAXONOMY_API; a_router: WSF_ROUTER)
-- Configure router mapping for web interface.
local
l_taxonomy_handler: TAXONOMY_TERM_ADMIN_HANDLER
l_voc_handler: TAXONOMY_VOCABULARY_ADMIN_HANDLER
do
a_router.handle ("/admin/taxonomy/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_admin_taxonomy (?, ?, a_api)), a_router.methods_get)
create l_taxonomy_handler.make (a_api, a_taxonomy_api)
a_router.handle ("/admin/taxonomy/term/", l_taxonomy_handler, a_router.methods_get_post)
a_router.handle ("/admin/taxonomy/term/{termid}", l_taxonomy_handler, a_router.methods_get_post)
create l_voc_handler.make (a_api, a_taxonomy_api)
a_router.handle ("/admin/taxonomy/vocabulary/", l_voc_handler, a_router.methods_get_post)
a_router.handle ("/admin/taxonomy/vocabulary/{vocid}", l_voc_handler, a_router.methods_get_post)
end
feature -- Handler
handle_admin_taxonomy (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
local
l_page: CMS_RESPONSE
lnk: CMS_LOCAL_LINK
do
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
create lnk.make ("Admin Vocabularies", "admin/taxonomy/vocabulary/")
l_page.add_to_primary_tabs (lnk)
create lnk.make ("Create terms", "admin/taxonomy/term/")
l_page.add_to_primary_tabs (lnk)
l_page.execute
end
feature -- Hooks
@@ -139,10 +179,14 @@ feature -- Hooks
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
do
-- Add the link to the taxonomy to the main menu
-- create lnk.make ("Taxonomy", "taxonomy/")
-- a_menu_system.primary_menu.extend (lnk)
-- Add the link to the taxonomy to the main menu
if a_response.has_permission ("admin taxonomy") then
create lnk.make ("Taxonomy", "admin/taxonomy/")
a_menu_system.management_menu.extend (lnk)
end
end
end

View File

@@ -19,6 +19,7 @@ feature {NONE} -- Initialization
make (nb: INTEGER)
do
create items.make (nb)
items.compare_objects
end
feature -- Access
@@ -48,6 +49,21 @@ feature -- Status report
Result := items.has (a_term)
end
term_by_id (tid: INTEGER_64): detachable CMS_TERM
-- Term of id `tid' contained in Current, if any.
do
across
items as ic
until
Result /= Void
loop
Result := ic.item
if Result.id /= tid then
Result := Void
end
end
end
feature -- Element change
wipe_out

View File

@@ -19,6 +19,7 @@ feature {NONE} -- Initialization
make (nb: INTEGER)
do
create items.make (nb)
items.compare_objects
end
feature -- Access
@@ -37,6 +38,21 @@ feature -- Access
end
end
item_by_id (a_id: INTEGER_64): detachable CMS_VOCABULARY
-- Vocabulary of id `a_id' contained in Current, if any.
do
across
items as ic
until
Result /= Void
loop
Result := ic.item
if Result.id /= a_id then
Result := Void
end
end
end
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_VOCABULARY]
-- <Precursor>
do

View File

@@ -0,0 +1,269 @@
note
description: "[
Request handler related to
/admin/taxonomy/term/{termid}
]"
date: "$Date$"
revision: "$revision$"
class
TAXONOMY_TERM_ADMIN_HANDLER
inherit
CMS_MODULE_HANDLER [CMS_TAXONOMY_API]
rename
module_api as taxonomy_api
end
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post
end
REFACTORING_HELPER
CMS_API_ACCESS
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for any kind of mapping.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI mapping.
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI-template mapping.
do
execute (req, res)
end
feature -- HTTP Methods
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: CMS_RESPONSE
tid: INTEGER_64
s: STRING
f: CMS_FORM
t: detachable CMS_TERM
l_parents: detachable CMS_VOCABULARY_COLLECTION
do
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
if tid > 0 then
t := taxonomy_api.term_by_id (tid)
end
end
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
if l_page.has_permission ("admin taxonomy") then
if t = Void then
l_page.set_title ("New term ...")
create t.make ("")
else
l_page.set_title (t.text)
end
create s.make_empty
f := edit_form (t, l_page, req)
f.process (l_page)
if
attached f.last_data as fd and then
fd.is_valid
then
if attached fd.string_item ("op") as l_op and then l_op.same_string ("Save changes") then
if attached fd.string_item ("text") as l_text then
t.set_text (l_text)
l_page.set_title (t.text)
end
if attached fd.string_item ("description") as l_description then
t.set_description (l_description)
end
if attached fd.string_item ("weight") as l_weight and then l_weight.is_integer then
t.set_weight (l_weight.to_integer)
end
taxonomy_api.save_term (t, Void)
if taxonomy_api.has_error then
fd.report_error ("Term creation failed!")
else
l_page.add_success_message ("Term creation succeed.")
s.append ("<div>View term: ")
s.append (l_page.link (t.text, "admin/taxonomy/term/" + t.id.out, Void))
s.append ("</div>")
if
attached fd.table_item ("vocabularies") as voc_tb and then
attached taxonomy_api.vocabularies (0, 0) as l_vocabularies
then
l_parents := taxonomy_api.vocabularies_for_term (t)
across
voc_tb as vid_ic
until
taxonomy_api.has_error
loop
if attached l_vocabularies.item_by_id (vid_ic.item.string_representation.to_integer_64) as v then
if l_parents /= Void and then attached l_parents.item_by_id (v.id) as l_v then
-- Already as parent!
l_parents.remove (l_v)
else
taxonomy_api.save_term (t, v)
l_vocabularies.remove (v)
end
end
end
if l_parents /= Void then
across
l_parents as v_ic
until
taxonomy_api.has_error
loop
taxonomy_api.remove_term_from_vocabulary (t, v_ic.item)
end
end
end
-- l_page.set_redirection (l_page.location)
end
else
fd.report_error ("Invalid form data!")
end
end
f.append_to_html (l_page.wsf_theme, s)
l_page.set_main_content (s)
l_page.execute
else
send_access_denied (req, res)
end
end
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
tid: INTEGER_64
s: STRING
f: CMS_FORM
t: detachable CMS_TERM
do
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
if tid > 0 then
t := taxonomy_api.term_by_id (tid)
end
end
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
if l_page.has_permission ("admin taxonomy") then
if t = Void then
l_page.set_title ("Create term ...")
create t.make ("")
else
l_page.set_title (t.text)
end
create s.make_empty
f := edit_form (t, l_page, req)
f.append_to_html (l_page.wsf_theme, s)
l_page.set_main_content (s)
l_page.execute
else
send_access_denied (req, res)
end
end
edit_form (t: CMS_TERM; a_page: CMS_RESPONSE; req: WSF_REQUEST): CMS_FORM
local
f: CMS_FORM
voc: detachable CMS_VOCABULARY
w_tf: WSF_FORM_TEXT_INPUT
w_txt: WSF_FORM_TEXTAREA
w_set: WSF_FORM_FIELD_SET
w_cb: WSF_FORM_CHECKBOX_INPUT
l_parents: detachable CMS_VOCABULARY_COLLECTION
do
create f.make (req.percent_encoded_path_info, "taxonomy")
if t.has_id then
f.extend_html_text (a_page.link ("View associated entities", "taxonomy/term/" + t.id.out, Void))
end
create w_tf.make_with_text ("text", t.text)
w_tf.set_is_required (True)
w_tf.set_label ("Text")
f.extend (w_tf)
create w_txt.make ("description")
w_txt.set_label ("Description")
w_txt.set_rows (3)
w_txt.set_cols (60)
if attached t.description as l_desc then
w_txt.set_text_value (api.html_encoded (l_desc))
end
w_txt.set_description ("Description of the terms; can be used by modules or administration.")
f.extend (w_txt)
create w_tf.make_with_text ("weight", t.weight.out)
w_tf.set_label ("Weight")
w_tf.set_description ("Terms are sorted in ascending order by weight.")
f.extend (w_tf)
if attached taxonomy_api.vocabularies (0, 0) as vocs then
if t.has_id then
l_parents := taxonomy_api.vocabularies_for_term (t)
end
create w_set.make
w_set.set_legend ("Associated vocabularies")
across
vocs as ic
loop
voc := ic.item
create w_cb.make_with_value ("vocabularies[]", ic.item.id.out)
w_cb.set_title (voc.name)
if
l_parents /= Void and then
across l_parents as p_ic some p_ic.item.id = ic.item.id end
then
w_cb.set_checked (True)
end
w_set.extend (w_cb)
end
if w_set.count > 0 then
f.extend (w_set)
end
end
f.extend (create {WSF_FORM_SUBMIT_INPUT}.make_with_text ("op", "Save changes"))
Result := f
end
end

View File

@@ -0,0 +1,414 @@
note
description: "[
Request handler related to
/admin/taxonomy/vocabulary/
/admin/taxonomy/vocabulary/{vocid}
]"
date: "$Date$"
revision: "$revision$"
class
TAXONOMY_VOCABULARY_ADMIN_HANDLER
inherit
CMS_MODULE_HANDLER [CMS_TAXONOMY_API]
rename
module_api as taxonomy_api
end
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get,
do_post
end
REFACTORING_HELPER
CMS_API_ACCESS
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for any kind of mapping.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI mapping.
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI-template mapping.
do
execute (req, res)
end
feature -- HTTP Methods
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
local
l_page: CMS_RESPONSE
voc: CMS_VOCABULARY
l_typename: READABLE_STRING_GENERAL
s: STRING
do
if not api.user_has_permission (current_user (req), "admin taxonomy") then
send_access_denied (req, res)
else
if attached {WSF_STRING} req.form_parameter ("op") as p_op then
if p_op.same_string ("New Vocabulary") then
if
attached {WSF_STRING} req.form_parameter ("vocabulary_name") as p_name and then
not p_name.is_empty
then
create voc.make (p_name.value)
taxonomy_api.save_vocabulary (voc)
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
if taxonomy_api.has_error then
l_page.add_error_message ("Vocabulary creation failed!")
else
l_page.add_success_message ("Vocabulary creation succeed!")
l_page.set_redirection ("admin/taxonomy/vocabulary/" + voc.id.out)
end
else
create {BAD_REQUEST_ERROR_CMS_RESPONSE} l_page.make (req, res, api)
end
elseif
p_op.same_string ("Save changes") and then
attached {WSF_STRING} req.path_parameter ("vocid") as p_vocid and then p_vocid.is_integer and then
attached taxonomy_api.vocabulary (p_vocid.value.to_integer_64) as l_vocabulary
then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
create s.make_empty
l_page.add_notice_message ("Vocabulary " + l_vocabulary.id.out)
if attached {WSF_STRING} req.form_parameter ("name") as p_name then
l_vocabulary.set_name (p_name.value)
end
if attached {WSF_STRING} req.form_parameter ("description") as p_desc then
l_vocabulary.set_description (p_desc.value)
end
if attached {WSF_STRING} req.form_parameter ("weight") as p_weight and then p_weight.is_integer then
l_vocabulary.set_weight (p_weight.integer_value)
end
taxonomy_api.save_vocabulary (l_vocabulary)
if taxonomy_api.has_error then
l_page.add_error_message ("Could not save vocabulary")
elseif
attached {WSF_TABLE} req.form_parameter ("typenames") as typenames_table
then
across
typenames_table as ic
loop
l_typename := ic.item.string_representation
create voc.make_from_term (l_vocabulary)
voc.set_associated_content_type (l_typename, False, False, False)
l_page.add_notice_message ("Content type :" + api.html_encoded (l_typename))
if attached {WSF_TABLE} req.form_parameter ({STRING_32} "vocabulary_" + l_typename.as_string_32) as opts then
across
opts as o_ic
loop
if o_ic.item.same_string ("tags") then
voc.set_is_tags (True)
elseif o_ic.item.same_string ("multiple") then
voc.allow_multiple_term (True)
elseif o_ic.item.same_string ("required") then
voc.set_is_term_required (True)
end
end
end
taxonomy_api.associate_vocabulary_with_type (voc, l_typename)
if taxonomy_api.has_error then
l_page.add_error_message ("Could not save vocabulary content type associations.")
end
end
end
if not taxonomy_api.has_error then
l_page.add_notice_message (l_page.link ({STRING_32} "Back to vocabulary %"" + l_vocabulary.name + "%"", "admin/taxonomy/vocabulary/" + l_vocabulary.id.out, Void))
end
l_page.set_main_content (s)
else
create {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE} l_page.make (req, res, api)
end
else
create {BAD_REQUEST_ERROR_CMS_RESPONSE} l_page.make (req, res, api)
end
l_page.execute
end
end
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
tid: INTEGER_64
do
if not api.user_has_permission (current_user (req), "admin taxonomy") then
send_access_denied (req, res)
else
if attached {WSF_STRING} req.path_parameter ("vocid") as p_vocid then
if p_vocid.is_integer then
tid := p_vocid.value.to_integer_64
end
end
if tid > 0 then
do_get_vocabulary (tid, req, res)
else
do_get_vocabularies (req, res)
end
end
end
do_get_vocabulary (tid: INTEGER_64; req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
require
valid_tid: tid > 0
local
l_page: CMS_RESPONSE
s: STRING
l_typename: detachable READABLE_STRING_8
v: detachable CMS_VOCABULARY
l_typenames: detachable LIST [READABLE_STRING_32]
f: CMS_FORM
wtb: WSF_WIDGET_TABLE
wtb_row: WSF_WIDGET_TABLE_ROW
wtb_item: WSF_WIDGET_TABLE_ITEM
voc: detachable CMS_VOCABULARY
l_term: detachable CMS_TERM
tf_input: WSF_FORM_TEXT_INPUT
tf_text: WSF_FORM_TEXTAREA
tf_num: WSF_FORM_NUMBER_INPUT
w_set: WSF_FORM_FIELD_SET
w_cb: WSF_FORM_CHECKBOX_INPUT
sub: WSF_FORM_SUBMIT_INPUT
do
voc := taxonomy_api.vocabulary (tid)
if voc /= Void then
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.set_title (voc.name)
taxonomy_api.fill_vocabularies_with_terms (voc)
create f.make (req.percent_encoded_path_info, "taxonomy")
create tf_input.make_with_text ("name", voc.name)
f.extend (tf_input)
create tf_text.make ("description")
tf_text.set_text_value (voc.description)
tf_text.set_description ("Description of the vocabulary; also used as intructions to present to the user when selecting terms.")
tf_text.set_rows (3)
f.extend (tf_text)
create tf_num.make_with_text ("weight", voc.weight.out)
tf_num.set_label ("weight")
tf_num.set_description ("Items are displayed in ascending order by weight.")
f.extend (tf_num)
create wtb.make
wtb.add_css_class ("with_border")
create wtb_row.make (2)
create wtb_item.make_with_text ("Text")
wtb_row.set_item (wtb_item, 1)
create wtb_item.make_with_text ("Description")
wtb_row.set_item (wtb_item, 2)
wtb.add_head_row (wtb_row)
across
voc as ic
loop
l_term := ic.item
create wtb_row.make (3)
wtb.add_row (wtb_row)
create wtb_item.make_with_text (l_page.link (ic.item.text, "admin/taxonomy/term/" + l_term.id.out, Void))
wtb_row.set_item (wtb_item, 1)
if attached ic.item.description as l_desc then
create wtb_item.make_with_text (api.html_encoded (l_desc))
else
create wtb_item.make_with_text ("")
end
wtb_row.set_item (wtb_item, 2)
end
if wtb.body_row_count > 0 then
f.extend (wtb)
else
f.extend_raw_text ("No terms.")
end
create w_set.make
w_set.set_legend ("Content types")
f.extend (w_set)
l_typenames := taxonomy_api.types_associated_with_vocabulary (voc)
create wtb.make
wtb.add_css_class ("with_border")
create wtb_row.make (5)
wtb_row.set_item (create {WSF_WIDGET_TABLE_ITEM}.make_with_text ("Type"), 1)
create wtb_item.make_with_text ("Settings ...")
wtb_item.add_html_attribute ("colspan", "3")
wtb_row.set_item (wtb_item, 2)
wtb.add_head_row (wtb_row)
across
api.content_types as ic
loop
create wtb_row.make (4)
wtb.add_row (wtb_row)
l_typename := ic.item.name
create w_cb.make_with_value ("typenames[]", api.html_encoded (l_typename))
w_cb.set_title (ic.item.name)
wtb_row.set_item (create {WSF_WIDGET_TABLE_ITEM}.make_with_content (w_cb), 1)
v := Void
if
l_typenames /= Void and then
across l_typenames as tn_ic some l_typename.is_case_insensitive_equal (tn_ic.item) end
then
w_cb.set_checked (True)
if attached taxonomy_api.vocabularies_for_type (l_typename) as v_list then
across v_list as v_ic until v /= Void loop
if v_ic.item.id = voc.id then
v := v_ic.item
end
end
end
end
create w_cb.make_with_value ("vocabulary_" + l_typename +"[]", "tags")
w_cb.set_title ("Tags")
w_cb.set_checked (v /= Void and then v.is_tags)
wtb_row.set_item (create {WSF_WIDGET_TABLE_ITEM}.make_with_content (w_cb), 2)
create w_cb.make_with_value ("vocabulary_" + l_typename +"[]", "multiple")
w_cb.set_title ("Multiple Select")
w_cb.set_checked (v /= Void and then v.multiple_terms_allowed)
wtb_row.set_item (create {WSF_WIDGET_TABLE_ITEM}.make_with_content (w_cb), 3)
create w_cb.make_with_value ("vocabulary_" + l_typename +"[]", "required")
w_cb.set_title ("Required")
w_cb.set_checked (v /= Void and then v.is_term_required)
wtb_row.set_item (create {WSF_WIDGET_TABLE_ITEM}.make_with_content (w_cb), 4)
end
if wtb.body_row_count > 0 then
w_set.extend (wtb)
end
create sub.make_with_text ("op", "Save changes")
f.extend (sub)
create s.make_empty
f.append_to_html (l_page.wsf_theme, s)
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
end
do_get_vocabularies (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
s: STRING
l_typenames: detachable LIST [READABLE_STRING_32]
f: CMS_FORM
wtb: WSF_WIDGET_TABLE
wtb_row: WSF_WIDGET_TABLE_ROW
wtb_item: WSF_WIDGET_TABLE_ITEM
voc: detachable CMS_VOCABULARY
tf_input: WSF_FORM_TEXT_INPUT
w_set: WSF_FORM_FIELD_SET
sub: WSF_FORM_SUBMIT_INPUT
do
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
create wtb.make
wtb.add_css_class ("with_border")
create wtb_row.make (3)
create wtb_item.make_with_text ("Name")
wtb_row.set_item (wtb_item, 1)
create wtb_item.make_with_text ("Type")
wtb_row.set_item (wtb_item, 2)
create wtb_item.make_with_text ("Operations")
wtb_row.set_item (wtb_item, 3)
wtb.add_head_row (wtb_row)
if attached taxonomy_api.vocabularies (0, 0) as lst then
across
lst as ic
loop
voc := ic.item
create wtb_row.make (3)
wtb.add_row (wtb_row)
create wtb_item.make_with_text (l_page.link (ic.item.name, "admin/taxonomy/vocabulary/" + ic.item.id.out, Void))
-- if attached ic.item.description as l_desc then
-- s.append (" : <em>")
-- s.append (api.html_encoded (l_desc))
-- s.append ("</em>")
-- end
wtb_row.set_item (wtb_item, 1)
l_typenames := taxonomy_api.types_associated_with_vocabulary (voc)
if l_typenames /= Void then
create s.make_empty
across
l_typenames as types_ic
loop
if not s.is_empty then
s.append_character (',')
s.append_character (' ')
end
s.append (api.html_encoded (types_ic.item))
end
create wtb_item.make_with_text (s)
wtb_row.set_item (wtb_item, 2)
end
s := l_page.link ("edit", "admin/taxonomy/vocabulary/" + voc.id.out, Void)
create wtb_item.make_with_text (s)
wtb_row.set_item (wtb_item, 3)
end
end
create f.make (req.percent_encoded_path_info, "taxonomy")
f.set_method_post
f.extend (wtb)
create w_set.make
w_set.set_legend ("Create a new vocabulary")
create tf_input.make_with_text ("vocabulary_name", "")
tf_input.set_label ("Vocabulary name")
w_set.extend (tf_input)
create sub.make_with_text ("op", "New Vocabulary")
w_set.extend (sub)
f.extend (w_set)
create s.make_empty
f.append_to_html (l_page.wsf_theme, s)
l_page.set_title ("Vocabularies")
l_page.set_main_content (s)
l_page.execute
end
end

View File

@@ -0,0 +1,129 @@
note
description: "[
Request handler related to
/taxonomy/vocabulary/
/taxonomy/vocabulary/{vocid}
]"
date: "$Date$"
revision: "$revision$"
class
TAXONOMY_VOCABULARY_HANDLER
inherit
CMS_MODULE_HANDLER [CMS_TAXONOMY_API]
rename
module_api as taxonomy_api
end
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
CMS_API_ACCESS
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for any kind of mapping.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI mapping.
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler for URI-template mapping.
do
execute (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
tid: INTEGER_64
s: STRING
do
if attached {WSF_STRING} req.path_parameter ("vocid") as p_vocid then
if p_vocid.is_integer then
tid := p_vocid.value.to_integer_64
end
end
if tid > 0 then
if attached taxonomy_api.vocabulary (tid) as voc then
-- Responding with `main_content_html (l_page)'.
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
l_page.set_title (voc.name)
taxonomy_api.fill_vocabularies_with_terms (voc)
create s.make_empty
s.append ("<ul class=%"taxonomy-terms%">")
across
voc as ic
loop
s.append ("<li>")
s.append (l_page.link (ic.item.text, "taxonomy/term/" + ic.item.id.out, Void))
if attached ic.item.description as l_desc then
s.append (" : <em>")
s.append (api.html_encoded (l_desc))
s.append ("</em>")
end
s.append ("</li>")
end
s.append ("</ul>")
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 {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
create s.make_empty
if attached taxonomy_api.vocabularies (0, 0) as lst then
s.append ("<ul class=%"taxonomy-vocabularies%">")
across
lst as ic
loop
s.append ("<li>")
s.append (l_page.link (ic.item.name, "taxonomy/vocabulary/" + ic.item.id.out, Void))
s.append ("</li>")
end
s.append ("</ul>")
else
s.append ("No vocabulary!")
end
l_page.set_main_content (s)
l_page.execute
end
end
end

View File

@@ -41,6 +41,24 @@ feature -- Access
deferred
end
vocabularies_for_term (a_term: CMS_TERM): detachable CMS_VOCABULARY_COLLECTION
-- Vocabularies including `a_term'.
deferred
end
is_term_inside_vocabulary (a_term: CMS_TERM; a_vocab: CMS_VOCABULARY): BOOLEAN
-- Is `a_term' inside `a_vocab' ?
require
valid_term: a_term.has_id
valid_vocabulary: a_vocab.has_id
deferred
end
types_associated_with_vocabulary (a_vocab: CMS_VOCABULARY): detachable LIST [READABLE_STRING_32]
-- Type names associated with `a_vocab'.
deferred
end
terms_count: INTEGER_64
-- Number of terms.
deferred
@@ -89,20 +107,28 @@ feature -- Access
feature -- Store
save_vocabulary (a_voc: CMS_VOCABULARY)
-- Insert or update vocabulary `a_voc'.
save_vocabulary (a_voc: CMS_VOCABULARY; a_with_terms: BOOLEAN)
-- Insert or update vocabulary `a_voc'
-- and also save {CMS_VOCABULARY}.terms if `a_with_terms' is True.
deferred
ensure
not error_handler.has_error implies a_voc.has_id and then vocabulary (a_voc.id) /= Void
end
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
-- Insert or update term `t' as part of vocabulary `voc'.
save_term (t: CMS_TERM; voc: detachable CMS_VOCABULARY)
-- Insert or update term `t' as part of vocabulary `voc' if set.
deferred
ensure
not error_handler.has_error implies t.has_id and then term_by_id (t.id) /= Void
end
remove_term_from_vocabulary (t: CMS_TERM; voc: CMS_VOCABULARY)
-- Remove term `t' from vocabulary `voc'.
require
t_has_id: t.has_id
deferred
end
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
-- Associate term `a_term' with `(a_type_name, a_entity)'.
require

View File

@@ -53,6 +53,21 @@ feature -- Access
do
end
vocabularies_for_term (a_term: CMS_TERM): detachable CMS_VOCABULARY_COLLECTION
-- <Precursor>
do
end
is_term_inside_vocabulary (a_term: CMS_TERM; a_vocab: CMS_VOCABULARY): BOOLEAN
-- <Precursor>
do
end
types_associated_with_vocabulary (a_vocab: CMS_VOCABULARY): detachable LIST [READABLE_STRING_32]
-- <Precursor>
do
end
terms_count: INTEGER_64
-- Number of terms.
do
@@ -85,18 +100,25 @@ feature -- Access
feature -- Store
save_vocabulary (a_voc: CMS_VOCABULARY)
-- Insert or update vocabulary `a_voc'.
save_vocabulary (a_voc: CMS_VOCABULARY; a_with_terms: BOOLEAN)
-- Insert or update vocabulary `a_voc'
-- and also save {CMS_VOCABULARY}.terms if `a_with_terms' is True.
do
error_handler.add_custom_error (-1, "not implemented", "save_vocabulary")
end
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
save_term (t: CMS_TERM; voc: detachable CMS_VOCABULARY)
-- <Precursor>
do
error_handler.add_custom_error (-1, "not implemented", "save_term")
end
remove_term_from_vocabulary (t: CMS_TERM; voc: CMS_VOCABULARY)
-- Remove term `t' from vocabulary `voc'.
do
error_handler.add_custom_error (-1, "not implemented", "remove_term_from_vocabulary")
end
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
do
error_handler.add_custom_error (-1, "not implemented", "associate_term_with_entity")

View File

@@ -232,21 +232,41 @@ feature -- Access
feature -- Store
save_vocabulary (voc: CMS_VOCABULARY)
save_vocabulary (voc: CMS_VOCABULARY; a_with_terms: BOOLEAN)
local
l_terms: CMS_TERM_COLLECTION
do
save_term (voc, create {CMS_VOCABULARY}.make_none)
across
voc.terms as ic
until
has_error
loop
save_term (ic.item, voc)
if a_with_terms then
l_terms := terms (voc, 0, 0)
across
voc.terms as ic
until
has_error
loop
if attached l_terms.term_by_id (ic.item.id) as t then
-- Already contained.
-- Remove from `l_terms' to leave only terms to remove.
l_terms.remove (t)
else
save_term (ic.item, voc)
end
end
across
l_terms as ic
until
has_error
loop
remove_term_from_vocabulary (ic.item, voc)
end
end
end
save_term (t: CMS_TERM; voc: CMS_VOCABULARY)
save_term (t: CMS_TERM; voc: detachable CMS_VOCABULARY)
local
l_parameters: STRING_TABLE [detachable ANY]
l_insert_voc: BOOLEAN
do
error_handler.reset
@@ -255,6 +275,8 @@ feature -- Store
l_parameters.put (t.description, "description")
l_parameters.put (t.weight, "weight")
l_insert_voc := voc /= Void and then is_term_inside_vocabulary (t, voc)
sql_begin_transaction
if t.has_id then
l_parameters.put (t.id, "tid")
@@ -263,9 +285,18 @@ feature -- Store
sql_insert (sql_insert_term, l_parameters)
t.set_id (last_inserted_term_id)
end
if not has_error then
if
not has_error and
voc /= Void and then
not l_insert_voc
then
l_parameters.wipe_out
l_parameters.put (t.id, "tid")
l_parameters.put (voc.id, "parent_tid")
if voc.has_id then
l_parameters.put (voc.id, "parent_tid")
else
l_parameters.put (0, "parent_tid")
end
sql_insert (sql_insert_term_in_vocabulary, l_parameters)
end
if has_error then
@@ -276,6 +307,19 @@ feature -- Store
sql_finalize
end
remove_term_from_vocabulary (t: CMS_TERM; voc: CMS_VOCABULARY)
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (2)
l_parameters.put (t.id, "tid")
l_parameters.put (voc.id, "parent_tid")
sql_modify (sql_remove_term_from_vocabulary, l_parameters)
sql_finalize
end
associate_term_with_entity (a_term: CMS_TERM; a_type_name: READABLE_STRING_GENERAL; a_entity: READABLE_STRING_GENERAL)
-- Associate term `a_term' with `(a_type_name, a_entity)'.
local
@@ -376,6 +420,90 @@ feature -- Vocabulary and types
end
end
is_term_inside_vocabulary (a_term: CMS_TERM; a_voc: CMS_VOCABULARY): BOOLEAN
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (2)
l_parameters.put (a_term.id, "tid")
l_parameters.put (a_voc.id, "parent_tid")
sql_query (sql_select_term_in_vocabulary, l_parameters)
sql_start
if not has_error or sql_after then
Result := sql_read_integer_64 (1) > 0
end
sql_finalize
end
vocabularies_for_term (a_term: CMS_TERM): detachable CMS_VOCABULARY_COLLECTION
-- <Precursor>
local
voc: detachable CMS_VOCABULARY
l_parameters: STRING_TABLE [detachable ANY]
l_parent_id: INTEGER_64
l_ids: ARRAYED_LIST [INTEGER_64]
do
error_handler.reset
create l_parameters.make (3)
l_parameters.put (a_term.id, "tid")
sql_query (sql_select_vocabularies_for_term, l_parameters)
create l_ids.make (1)
from
sql_start
until
sql_after or has_error
loop
l_parent_id := sql_read_integer_64 (1)
l_ids.force (l_parent_id)
sql_forth
end
sql_finalize
if l_ids.count > 0 then
create Result.make (1)
across
l_ids as ic
loop
voc := vocabulary (ic.item)
if voc /= Void then
Result.force (voc)
end
end
if Result.count = 0 then
Result := Void
end
end
end
types_associated_with_vocabulary (a_vocab: CMS_VOCABULARY): detachable LIST [READABLE_STRING_32]
-- Type names associated with `a_vocab'.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
create l_parameters.make (1)
l_parameters.put (a_vocab.id, "tid")
sql_query (sql_select_type_associated_with_vocabulary, l_parameters)
create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (3)
from
sql_start
until
sql_after or has_error
loop
if attached sql_read_string_32 (1) as l_typename then
Result.force (l_typename)
end
sql_forth
end
sql_finalize
end
associate_vocabulary_with_type (a_voc: CMS_VOCABULARY; a_type_name: READABLE_STRING_GENERAL)
-- <Precursor>
local
@@ -396,10 +524,17 @@ feature -- Vocabulary and types
i := i | mask_is_required
end
l_parameters.put ((- i).out, "entity")
l_parameters.put (a_type_name, "type")
sql_insert (sql_insert_term_index, l_parameters)
if
attached vocabularies_for_type (a_type_name) as lst and then
across lst as ic some a_voc.id = ic.item.id end
then
sql_modify (sql_update_term_index, l_parameters)
else
sql_insert (sql_insert_term_index, l_parameters)
end
sql_finalize
end
@@ -464,6 +599,20 @@ feature {NONE} -- Queries
]"
-- Terms under :parent_tid.
sql_select_vocabularies_for_term: STRING = "[
SELECT parent
FROM taxonomy_hierarchy
WHERE tid = :tid
;
]"
sql_select_term_in_vocabulary: STRING = "[
SELECT count(*)
FROM taxonomy_hierarchy
WHERE tid = :tid and parent = :parent_tid
;
]"
sql_select_terms_with_range: STRING = "[
SELECT taxonomy_term.tid, taxonomy_term.text, taxonomy_term.weight, taxonomy_term.description
FROM taxonomy_term INNER JOIN taxonomy_hierarchy ON taxonomy_term.tid = taxonomy_hierarchy.tid
@@ -505,6 +654,10 @@ feature {NONE} -- Queries
VALUES (:tid, :parent_tid);
]"
sql_remove_term_from_vocabulary: STRING = "[
DELETE FROM taxonomy_hierarchy WHERE tid=:tid AND parent=:parent_tid;
]"
sql_select_terms_of_entity: STRING = "[
SELECT tid FROM taxonomy_index WHERE type=:type AND entity=:entity;
]"
@@ -527,6 +680,19 @@ feature {NONE} -- Queries
WHERE type=:type AND entity <= 0;
]"
sql_select_type_associated_with_vocabulary: STRING = "[
SELECT type
FROM taxonomy_index
WHERE tid=:tid AND entity <= 0;
]"
sql_update_term_index: STRING = "[
UPDATE taxonomy_index
SET entity=:entity
WHERE tid=:tid and type=:type
;
]"
sql_insert_term_index: STRING = "[
INSERT INTO taxonomy_index (tid, entity, type)
VALUES (:tid, :entity, :type);

View File

@@ -19,3 +19,8 @@ ul.taxonomy li:hover {
border-bottom: solid 1px #66f;
background-color: #ddf;
}
table.taxonomy td {
border: solid 1px #ccc;
padding: 2px;
}

View File

@@ -19,3 +19,9 @@ ul.taxonomy {
}
}
}
table.taxonomy {
td {
border: solid 1px #ccc;
padding: 2px;
}
}

View File

@@ -15,7 +15,7 @@ inherit
REFACTORING_HELPER
CMS_ENCODERS
CMS_REQUEST_UTIL
create
make
@@ -407,7 +407,7 @@ feature {NONE} -- Hooks
l_hooks: like hooks
do
l_hooks := hooks
register_hooks (l_hooks)
setup_core_hooks (l_hooks)
across
enabled_modules as ic
loop
@@ -436,7 +436,7 @@ feature -- Query: API
feature -- Hooks
register_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
setup_core_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
-- Register hooks associated with the cms core.
do
a_hooks.subscribe_to_export_hook (Current)

View File

@@ -72,7 +72,6 @@ feature {NONE} -- Initialization
l_module: CMS_MODULE
l_enabled_modules: CMS_MODULE_COLLECTION
do
api.register_hooks (hooks)
l_enabled_modules := api.enabled_modules
across
l_enabled_modules as ic
@@ -984,6 +983,26 @@ feature -- Theme
end
end
feature -- Theme helpers
wsf_theme: WSF_THEME
-- WSF Theme from CMS `theme' for Current response.
local
t: like internal_wsf_theme
do
t := internal_wsf_theme
if t = Void then
create {CMS_TO_WSF_THEME} t.make (Current, theme)
internal_wsf_theme := t
end
Result := t
end
feature {NONE} -- Theme helpers
internal_wsf_theme: detachable WSF_THEME
-- Once per object for `wsf_theme'.
feature -- Element Change
set_status_code (a_status: INTEGER)