Added blog module as example, this is far from being a real blog module.
but this is an example about on to add a new content type, and support it. Fixed new node form workflow. The current state is not final, it requires many changes, but for now, it implements a node editing workflow.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
|
||||
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_blog_module" location="modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
|
||||
<!--
|
||||
|
||||
103
examples/demo/modules/blog/cms_blog.e
Normal file
103
examples/demo/modules/blog/cms_blog.e
Normal file
@@ -0,0 +1,103 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOG}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_BLOG
|
||||
|
||||
inherit
|
||||
CMS_NODE
|
||||
redefine
|
||||
make_empty,
|
||||
import_node
|
||||
end
|
||||
|
||||
create
|
||||
make_empty,
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_empty
|
||||
do
|
||||
Precursor
|
||||
end
|
||||
|
||||
feature {CMS_CONTENT_TYPE} -- Conversion
|
||||
|
||||
import_node (a_node: CMS_NODE)
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor (a_node)
|
||||
if attached {CMS_BLOG} a_node as l_blog then
|
||||
-- l_blog
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: READABLE_STRING_8
|
||||
once
|
||||
Result := {CMS_BLOG_CONTENT_TYPE}.name
|
||||
end
|
||||
|
||||
feature -- Access: content
|
||||
|
||||
summary: detachable READABLE_STRING_8
|
||||
-- A short summary of the node.
|
||||
|
||||
content: detachable READABLE_STRING_8
|
||||
-- Content of the node.
|
||||
|
||||
format: detachable READABLE_STRING_8
|
||||
-- Format associated with `content' and `summary'.
|
||||
-- For example: text, mediawiki, html, etc
|
||||
|
||||
tags: detachable ARRAYED_LIST [READABLE_STRING_32]
|
||||
-- Optional tags
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_content (a_content: like content; a_summary: like summary; a_format: like format)
|
||||
do
|
||||
content := a_content
|
||||
summary := a_summary
|
||||
format := a_format
|
||||
end
|
||||
|
||||
add_tag (a_tag: READABLE_STRING_32)
|
||||
-- Set `parent' to `a_page'
|
||||
require
|
||||
not a_tag.is_whitespace
|
||||
local
|
||||
l_tags: like tags
|
||||
do
|
||||
l_tags := tags
|
||||
if l_tags = Void then
|
||||
create l_tags.make (1)
|
||||
tags := l_tags
|
||||
end
|
||||
l_tags.force (a_tag)
|
||||
end
|
||||
|
||||
set_tags_from_string (a_tags: READABLE_STRING_32)
|
||||
local
|
||||
t: STRING_32
|
||||
do
|
||||
tags := Void
|
||||
across
|
||||
a_tags.split (',') as ic
|
||||
loop
|
||||
t := ic.item
|
||||
t.left_adjust
|
||||
t.right_adjust
|
||||
if not t.is_whitespace then
|
||||
add_tag (t)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
65
examples/demo/modules/blog/cms_blog_content_type.e
Normal file
65
examples/demo/modules/blog/cms_blog_content_type.e
Normal file
@@ -0,0 +1,65 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOG_CONTENT_TYPE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_BLOG_CONTENT_TYPE
|
||||
|
||||
inherit
|
||||
CMS_CONTENT_TYPE
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
do
|
||||
Precursor
|
||||
create {ARRAYED_LIST [like available_formats.item]} available_formats.make (3)
|
||||
available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT})
|
||||
available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT})
|
||||
available_formats.extend (create {FULL_HTML_CONTENT_FORMAT})
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "blog"
|
||||
-- Internal name.
|
||||
|
||||
title: STRING_32 = "Blog"
|
||||
-- Human readable name.
|
||||
|
||||
description: STRING_32 = "Content published as a blog post."
|
||||
-- Optional description
|
||||
|
||||
feature -- Access
|
||||
|
||||
available_formats: LIST [CONTENT_FORMAT]
|
||||
-- Available formats for Current type.
|
||||
|
||||
feature -- Factory
|
||||
|
||||
new_node_with_title (a_title: READABLE_STRING_32; a_partial_node: detachable CMS_NODE): like new_node
|
||||
-- New node with `a_title' and fill from partial `a_partial_node' if set.
|
||||
do
|
||||
create Result.make (a_title)
|
||||
if a_partial_node /= Void then
|
||||
Result.import_node (a_partial_node)
|
||||
Result.set_title (a_title)
|
||||
end
|
||||
end
|
||||
|
||||
new_node (a_partial_node: detachable CMS_NODE): CMS_BLOG
|
||||
-- New node based on partial `a_partial_node', or from none.
|
||||
do
|
||||
create Result.make_empty
|
||||
if a_partial_node /= Void then
|
||||
Result.import_node (a_partial_node)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOG_CONTENT_TYPE_WEBFORM_MANAGER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_BLOG_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
|
||||
inherit
|
||||
CMS_NODE_CONTENT_TYPE_WEBFORM_MANAGER [CMS_BLOG]
|
||||
redefine
|
||||
content_type,
|
||||
fill_edit_form,
|
||||
change_node,
|
||||
new_node
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: CMS_BLOG_CONTENT_TYPE
|
||||
-- Associated content type.
|
||||
|
||||
feature -- form
|
||||
|
||||
fill_edit_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable like new_node)
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
fset: WSF_FORM_FIELD_SET
|
||||
ta: WSF_FORM_TEXTAREA
|
||||
tselect: WSF_FORM_SELECT
|
||||
opt: WSF_FORM_SELECT_OPTION
|
||||
s: STRING_32
|
||||
do
|
||||
Precursor (response, f, a_node)
|
||||
create ti.make ("tags")
|
||||
ti.set_label ("Tags")
|
||||
ti.set_size (70)
|
||||
if a_node /= Void and then attached a_node.tags as l_tags then
|
||||
create s.make_empty
|
||||
across
|
||||
l_tags as ic
|
||||
loop
|
||||
if not s.is_empty then
|
||||
s.append_character (',')
|
||||
end
|
||||
s.append (ic.item)
|
||||
end
|
||||
ti.set_text_value (s)
|
||||
end
|
||||
ti.set_is_required (False)
|
||||
f.extend (ti)
|
||||
end
|
||||
|
||||
change_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: like new_node)
|
||||
do
|
||||
Precursor (response, fd, a_node)
|
||||
if attached fd.string_item ("tags") as l_tags then
|
||||
a_node.set_tags_from_string (l_tags)
|
||||
end
|
||||
end
|
||||
|
||||
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): like content_type.new_node
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := Precursor (response, fd, a_node)
|
||||
if attached fd.string_item ("tags") as l_tags then
|
||||
Result.set_tags_from_string (l_tags)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
26
examples/demo/modules/blog/cms_blog_module-safe.ecf
Normal file
26
examples/demo/modules/blog/cms_blog_module-safe.ecf
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_blog_module" uuid="C92F6E1E-2222-4414-9B6E-AA680E324D42" library_target="cms_blog_module">
|
||||
<target name="cms_blog_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-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_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
121
examples/demo/modules/blog/cms_blog_module.e
Normal file
121
examples/demo/modules/blog/cms_blog_module.e
Normal file
@@ -0,0 +1,121 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOG_MODULE}."
|
||||
author: ""
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
CMS_BLOG_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
name := "Blog demo module"
|
||||
version := "1.0"
|
||||
description := "Service to demonstrate new node for blog"
|
||||
package := "demo"
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
-- <Precursor>
|
||||
local
|
||||
ct: CMS_BLOG_CONTENT_TYPE
|
||||
do
|
||||
Precursor (api)
|
||||
|
||||
if attached {CMS_NODE_API} api.module_api ({NODE_MODULE}) as l_node_api then
|
||||
create ct
|
||||
l_node_api.add_content_type (ct)
|
||||
l_node_api.add_content_type_webform_manager (create {CMS_BLOG_CONTENT_TYPE_WEBFORM_MANAGER}.make (ct))
|
||||
-- Add support for CMS_BLOG, which requires a storage extension to store the optional "tags" value
|
||||
-- For now, we only have extension based on SQL statement.
|
||||
if attached {CMS_NODE_STORAGE_SQL} l_node_api.node_storage as l_sql_node_storage then
|
||||
l_sql_node_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_BLOG_EXTENSION}.make (l_sql_node_storage))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
sql: STRING
|
||||
do
|
||||
-- Schema
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
if not l_sql_storage.sql_table_exists ("blog_post_nodes") then
|
||||
sql := "[
|
||||
CREATE TABLE "blog_post_nodes"(
|
||||
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||
"revision" INTEGER,
|
||||
"tags" VARCHAR(255)
|
||||
);
|
||||
]"
|
||||
l_sql_storage.sql_execute_script (sql)
|
||||
if l_sql_storage.has_error then
|
||||
api.logger.put_error ("Could not initialize database for blog module", generating_type)
|
||||
end
|
||||
end
|
||||
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
router (a_api: CMS_API): WSF_ROUTER
|
||||
-- Node router.
|
||||
do
|
||||
create Result.make (1)
|
||||
Result.handle_with_request_methods ("/blogs/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_blogs (?,?, a_api)), Result.methods_get)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
do
|
||||
a_response.subscribe_to_menu_system_alter_hook (Current)
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
do
|
||||
create lnk.make ("Blogs", "/blogs/")
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
end
|
||||
|
||||
feature -- Handler
|
||||
|
||||
handle_blogs (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
|
||||
local
|
||||
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
do
|
||||
create r.make (req, res, a_api)
|
||||
r.set_main_content ("Blog module is in development ...")
|
||||
r.execute
|
||||
end
|
||||
|
||||
end
|
||||
116
examples/demo/modules/blog/cms_node_storage_sql_blog_extension.e
Normal file
116
examples/demo/modules/blog/cms_node_storage_sql_blog_extension.e
Normal file
@@ -0,0 +1,116 @@
|
||||
note
|
||||
description: "Storage extension for Blog nodes."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_NODE_STORAGE_SQL_BLOG_EXTENSION
|
||||
|
||||
inherit
|
||||
CMS_NODE_STORAGE_EXTENSION [CMS_BLOG]
|
||||
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
rename
|
||||
sql_storage as node_storage
|
||||
redefine
|
||||
node_storage
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
node_storage: CMS_NODE_STORAGE_SQL
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: STRING
|
||||
once
|
||||
Result := {CMS_BLOG_CONTENT_TYPE}.name
|
||||
end
|
||||
|
||||
feature -- Persistence
|
||||
|
||||
store (a_node: CMS_BLOG)
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_new_tags: detachable STRING_32
|
||||
l_previous_tags: detachable STRING_32
|
||||
l_update: BOOLEAN
|
||||
do
|
||||
error_handler.reset
|
||||
if attached api as l_api then
|
||||
l_api.logger.put_information (generator + ".store", Void)
|
||||
end
|
||||
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
|
||||
sql_query (sql_select_blog_data, l_parameters)
|
||||
if not has_error then
|
||||
if sql_rows_count = 1 then
|
||||
l_previous_tags := sql_read_string_32 (3)
|
||||
l_update := True
|
||||
end
|
||||
if attached a_node.tags as l_tags and then not l_tags.is_empty then
|
||||
create l_new_tags.make (0)
|
||||
across
|
||||
l_tags as ic
|
||||
loop
|
||||
if not l_new_tags.is_empty then
|
||||
l_new_tags.append_character (',')
|
||||
end
|
||||
l_new_tags.append (ic.item)
|
||||
end
|
||||
else
|
||||
l_new_tags := Void
|
||||
end
|
||||
l_parameters.put (l_new_tags, "tags")
|
||||
if l_update and l_new_tags /~ l_previous_tags then
|
||||
sql_change (sql_update_blog_data, l_parameters)
|
||||
elseif l_new_tags /= Void then
|
||||
sql_change (sql_insert_blog_data, l_parameters)
|
||||
else
|
||||
-- no blog data, means everything is empty.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
load (a_node: CMS_BLOG)
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
n: INTEGER
|
||||
ct: CMS_BLOG_CONTENT_TYPE
|
||||
do
|
||||
error_handler.reset
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
sql_query (sql_select_blog_data, l_parameters)
|
||||
if not has_error then
|
||||
n := sql_rows_count
|
||||
if n = 1 then
|
||||
-- nid, revision, parent
|
||||
if
|
||||
attached sql_read_string_32 (3) as l_tags and then
|
||||
not l_tags.is_whitespace
|
||||
then
|
||||
-- FIXME: find a simple way to access the declared content types.
|
||||
a_node.set_tags_from_string (l_tags)
|
||||
end
|
||||
else
|
||||
check unique_data: n = 0 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- SQL
|
||||
|
||||
sql_select_blog_data: STRING = "SELECT nid, revision, tags FROM blog_post_nodes WHERE nid =:nid AND revision=:revision;"
|
||||
sql_insert_blog_data: STRING = "INSERT INTO blog_post_nodes (nid, revision, tags) VALUES (:nid, :revision, :tags);"
|
||||
sql_update_blog_data: STRING = "UPDATE blog_post_nodes SET nid=:nid, revision=:revision, tags=:tags WHERE nid=:nid AND revision=:revision;"
|
||||
|
||||
end
|
||||
@@ -10,7 +10,10 @@ class
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
register_hooks
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
@@ -30,6 +33,51 @@ feature {NONE} -- Initialization
|
||||
package := "demo"
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor (api)
|
||||
|
||||
-- Add support for CMS_PAGE, which requires a storage extension to store the optional "parent" id.
|
||||
-- For now, we only have extension based on SQL statement.
|
||||
-- if attached {CMS_NODE_STORAGE_SQL} l_node_api.node_storage as l_sql_node_storage then
|
||||
-- l_sql_node_storage.register_node_storage_extension (create {CMS_NODE_STORAGE_SQL_PAGE_EXTENSION}.make (l_sql_node_storage))
|
||||
-- end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
sql: STRING
|
||||
do
|
||||
-- Schema
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
if not l_sql_storage.sql_table_exists ("tb_demo") then
|
||||
sql := "[
|
||||
CREATE TABLE "tb_demo"(
|
||||
"demo_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("demo_id">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"value" TEXT
|
||||
);
|
||||
]"
|
||||
l_sql_storage.sql_execute_script (sql)
|
||||
if l_sql_storage.has_error then
|
||||
api.logger.put_error ("Could not initialize database for demo module", generating_type)
|
||||
end
|
||||
end
|
||||
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
router (a_api: CMS_API): WSF_ROUTER
|
||||
@@ -84,37 +132,11 @@ feature -- Hooks
|
||||
|
||||
feature -- Handler
|
||||
|
||||
initialize_module (a_api: CMS_API)
|
||||
local
|
||||
sql: STRING
|
||||
do
|
||||
if attached {CMS_STORAGE_SQL_I} a_api.storage as sql_db then
|
||||
sql_db.sql_query ("select count(*) from tb_demo;", Void)
|
||||
if sql_db.has_error then
|
||||
-- Initialize db for demo module
|
||||
sql := "[
|
||||
CREATE TABLE "tb_demo"(
|
||||
"did" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("did">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"value" TEXT
|
||||
);
|
||||
]"
|
||||
sql_db.reset_error
|
||||
sql_db.sql_change (sql, Void)
|
||||
if sql_db.has_error then
|
||||
a_api.logger.put_error ("Could not initialize database for demo module", generating_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
handle_demo,
|
||||
handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
|
||||
local
|
||||
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
do
|
||||
initialize_module (a_api)
|
||||
|
||||
create r.make (req, res, a_api)
|
||||
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
|
||||
r.add_error_message ("NODE Module: not yet implemented")
|
||||
|
||||
@@ -144,6 +144,10 @@ feature -- CMS setup
|
||||
create {CMS_DEMO_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_BLOG_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
end
|
||||
|
||||
setup_storage (a_setup: CMS_SETUP)
|
||||
|
||||
@@ -45,7 +45,7 @@ feature {NONE} -- Implementation
|
||||
add_content_type_webform_manager (create {CMS_PAGE_CONTENT_TYPE_WEBFORM_MANAGER}.make (ct))
|
||||
end
|
||||
|
||||
feature {NODE_MODULE} -- Access nodes storage.
|
||||
feature {CMS_MODULE} -- Access nodes storage.
|
||||
|
||||
node_storage: CMS_NODE_STORAGE_I
|
||||
|
||||
@@ -104,7 +104,7 @@ feature -- URL
|
||||
-- or URI of path for selection of new content possibilities if ct is Void.
|
||||
do
|
||||
if ct /= Void then
|
||||
Result := "/node/new/" + ct.name
|
||||
Result := "/node/add/" + ct.name
|
||||
else
|
||||
Result := "/node/new"
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ feature {CMS_CONTENT_TYPE} -- Conversion
|
||||
do
|
||||
Precursor (a_node)
|
||||
if attached {CMS_PAGE} a_node as l_page then
|
||||
set_parent (l_page)
|
||||
set_parent (l_page.parent)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ feature -- Forms ...
|
||||
end
|
||||
|
||||
change_node (response: NODE_RESPONSE; a_form_data: WSF_FORM_DATA; a_node: CMS_NODE)
|
||||
require
|
||||
a_node.has_id
|
||||
-- require
|
||||
-- a_node.has_id
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
159
src/modules/node/handler/cms_node_content_type_webform_manager.e
Normal file
159
src/modules/node/handler/cms_node_content_type_webform_manager.e
Normal file
@@ -0,0 +1,159 @@
|
||||
note
|
||||
description: "Summary description for {CMS_NODE_CONTENT_TYPE_WEBFORM_MANAGER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_NODE_CONTENT_TYPE_WEBFORM_MANAGER [G -> CMS_NODE]
|
||||
|
||||
inherit
|
||||
CMS_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
redefine
|
||||
content_type
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: CMS_CONTENT_TYPE
|
||||
-- Associated content type.
|
||||
|
||||
feature -- Forms ...
|
||||
|
||||
fill_edit_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable like new_node)
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
fset: WSF_FORM_FIELD_SET
|
||||
ta: WSF_FORM_TEXTAREA
|
||||
tselect: WSF_FORM_SELECT
|
||||
opt: WSF_FORM_SELECT_OPTION
|
||||
do
|
||||
create ti.make ("title")
|
||||
ti.set_label ("Title")
|
||||
ti.set_size (70)
|
||||
if a_node /= Void then
|
||||
ti.set_text_value (a_node.title)
|
||||
end
|
||||
ti.set_is_required (True)
|
||||
f.extend (ti)
|
||||
|
||||
f.extend_html_text ("<br/>")
|
||||
|
||||
create ta.make ("body")
|
||||
ta.set_rows (10)
|
||||
ta.set_cols (70)
|
||||
if a_node /= Void then
|
||||
ta.set_text_value (a_node.content)
|
||||
end
|
||||
-- ta.set_label ("Body")
|
||||
ta.set_description ("This is the main content")
|
||||
ta.set_is_required (False)
|
||||
|
||||
create fset.make
|
||||
fset.set_legend ("Body")
|
||||
fset.extend (ta)
|
||||
|
||||
fset.extend_html_text ("<br/>")
|
||||
|
||||
create tselect.make ("format")
|
||||
tselect.set_label ("Body's format")
|
||||
tselect.set_is_required (True)
|
||||
across
|
||||
content_type.available_formats as c
|
||||
loop
|
||||
create opt.make (c.item.name, c.item.title)
|
||||
if attached c.item.html_help as f_help then
|
||||
opt.set_description ("<ul>" + f_help + "</ul>")
|
||||
end
|
||||
tselect.add_option (opt)
|
||||
end
|
||||
if a_node /= Void and then attached a_node.format as l_format then
|
||||
tselect.set_text_by_value (l_format)
|
||||
end
|
||||
|
||||
fset.extend (tselect)
|
||||
|
||||
f.extend (fset)
|
||||
|
||||
end
|
||||
|
||||
change_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: like new_node)
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
do
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
check a_node.id = l_id end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
a_node.set_title (l_title)
|
||||
end
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
a_node.set_content (b, Void, f.name) -- FIXME: summary
|
||||
end
|
||||
end
|
||||
|
||||
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): like content_type.new_node
|
||||
-- <Precursor>
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
l_node: detachable like new_node
|
||||
do
|
||||
l_node := a_node
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
if l_node /= Void then
|
||||
check l_node.id = l_id end
|
||||
else
|
||||
if attached {like new_node} response.node_api.node (l_id) as n then
|
||||
l_node := n
|
||||
else
|
||||
-- FIXME: Error
|
||||
end
|
||||
end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node (Void)
|
||||
l_node.set_title (l_title)
|
||||
else
|
||||
l_node.set_title (l_title)
|
||||
end
|
||||
else
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node_with_title ("...", Void)
|
||||
end
|
||||
end
|
||||
l_node.set_author (response.user)
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
l_node.set_content (b, Void, f.name)
|
||||
end
|
||||
Result := l_node
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ class
|
||||
CMS_PAGE_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
|
||||
inherit
|
||||
CMS_CONTENT_TYPE_WEBFORM_MANAGER
|
||||
CMS_NODE_CONTENT_TYPE_WEBFORM_MANAGER [CMS_PAGE]
|
||||
redefine
|
||||
content_type
|
||||
end
|
||||
@@ -23,138 +23,138 @@ feature -- Access
|
||||
|
||||
feature -- Forms ...
|
||||
|
||||
fill_edit_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
fset: WSF_FORM_FIELD_SET
|
||||
ta: WSF_FORM_TEXTAREA
|
||||
tselect: WSF_FORM_SELECT
|
||||
opt: WSF_FORM_SELECT_OPTION
|
||||
do
|
||||
create ti.make ("title")
|
||||
ti.set_label ("Title")
|
||||
ti.set_size (70)
|
||||
if a_node /= Void then
|
||||
ti.set_text_value (a_node.title)
|
||||
end
|
||||
ti.set_is_required (True)
|
||||
f.extend (ti)
|
||||
-- fill_edit_form (response: NODE_RESPONSE; f: CMS_FORM; a_node: detachable CMS_NODE)
|
||||
-- local
|
||||
-- ti: WSF_FORM_TEXT_INPUT
|
||||
-- fset: WSF_FORM_FIELD_SET
|
||||
-- ta: WSF_FORM_TEXTAREA
|
||||
-- tselect: WSF_FORM_SELECT
|
||||
-- opt: WSF_FORM_SELECT_OPTION
|
||||
-- do
|
||||
-- create ti.make ("title")
|
||||
-- ti.set_label ("Title")
|
||||
-- ti.set_size (70)
|
||||
-- if a_node /= Void then
|
||||
-- ti.set_text_value (a_node.title)
|
||||
-- end
|
||||
-- ti.set_is_required (True)
|
||||
-- f.extend (ti)
|
||||
|
||||
f.extend_html_text ("<br/>")
|
||||
-- f.extend_html_text ("<br/>")
|
||||
|
||||
create ta.make ("body")
|
||||
ta.set_rows (10)
|
||||
ta.set_cols (70)
|
||||
if a_node /= Void then
|
||||
ta.set_text_value (a_node.content)
|
||||
end
|
||||
-- ta.set_label ("Body")
|
||||
ta.set_description ("This is the main content")
|
||||
ta.set_is_required (False)
|
||||
-- create ta.make ("body")
|
||||
-- ta.set_rows (10)
|
||||
-- ta.set_cols (70)
|
||||
-- if a_node /= Void then
|
||||
-- ta.set_text_value (a_node.content)
|
||||
-- end
|
||||
---- ta.set_label ("Body")
|
||||
-- ta.set_description ("This is the main content")
|
||||
-- ta.set_is_required (False)
|
||||
|
||||
create fset.make
|
||||
fset.set_legend ("Body")
|
||||
fset.extend (ta)
|
||||
-- create fset.make
|
||||
-- fset.set_legend ("Body")
|
||||
-- fset.extend (ta)
|
||||
|
||||
fset.extend_html_text ("<br/>")
|
||||
-- fset.extend_html_text ("<br/>")
|
||||
|
||||
create tselect.make ("format")
|
||||
tselect.set_label ("Body's format")
|
||||
tselect.set_is_required (True)
|
||||
across
|
||||
content_type.available_formats as c
|
||||
loop
|
||||
create opt.make (c.item.name, c.item.title)
|
||||
if attached c.item.html_help as f_help then
|
||||
opt.set_description ("<ul>" + f_help + "</ul>")
|
||||
end
|
||||
tselect.add_option (opt)
|
||||
end
|
||||
if a_node /= Void and then attached a_node.format as l_format then
|
||||
tselect.set_text_by_value (l_format)
|
||||
end
|
||||
-- create tselect.make ("format")
|
||||
-- tselect.set_label ("Body's format")
|
||||
-- tselect.set_is_required (True)
|
||||
-- across
|
||||
-- content_type.available_formats as c
|
||||
-- loop
|
||||
-- create opt.make (c.item.name, c.item.title)
|
||||
-- if attached c.item.html_help as f_help then
|
||||
-- opt.set_description ("<ul>" + f_help + "</ul>")
|
||||
-- end
|
||||
-- tselect.add_option (opt)
|
||||
-- end
|
||||
-- if a_node /= Void and then attached a_node.format as l_format then
|
||||
-- tselect.set_text_by_value (l_format)
|
||||
-- end
|
||||
|
||||
fset.extend (tselect)
|
||||
-- fset.extend (tselect)
|
||||
|
||||
f.extend (fset)
|
||||
-- f.extend (fset)
|
||||
|
||||
end
|
||||
-- end
|
||||
|
||||
change_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: like new_node)
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
do
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
check a_node.id = l_id end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
a_node.set_title (l_title)
|
||||
end
|
||||
-- change_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: like new_node)
|
||||
-- local
|
||||
-- b: detachable READABLE_STRING_8
|
||||
-- f: detachable CONTENT_FORMAT
|
||||
-- do
|
||||
-- if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
-- check a_node.id = l_id end
|
||||
-- end
|
||||
-- if attached fd.string_item ("title") as l_title then
|
||||
-- a_node.set_title (l_title)
|
||||
-- end
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
a_node.set_content (b, Void, f.name) -- FIXME: summary
|
||||
end
|
||||
end
|
||||
-- if attached fd.string_item ("body") as l_body then
|
||||
-- b := l_body
|
||||
-- end
|
||||
-- if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- else
|
||||
-- f := response.api.formats.default_format
|
||||
-- end
|
||||
-- if b /= Void then
|
||||
-- a_node.set_content (b, Void, f.name) -- FIXME: summary
|
||||
-- end
|
||||
-- end
|
||||
|
||||
new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): CMS_PAGE
|
||||
-- <Precursor>
|
||||
local
|
||||
b: detachable READABLE_STRING_8
|
||||
f: detachable CONTENT_FORMAT
|
||||
l_node: detachable like new_node
|
||||
do
|
||||
l_node := a_node
|
||||
if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
if l_node /= Void then
|
||||
check l_node.id = l_id end
|
||||
else
|
||||
if attached {like new_node} response.node_api.node (l_id) as n then
|
||||
l_node := n
|
||||
else
|
||||
-- FIXME: Error
|
||||
end
|
||||
end
|
||||
end
|
||||
if attached fd.string_item ("title") as l_title then
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node (Void)
|
||||
l_node.set_title (l_title)
|
||||
else
|
||||
l_node.set_title (l_title)
|
||||
end
|
||||
else
|
||||
if l_node = Void then
|
||||
l_node := content_type.new_node_with_title ("...", Void)
|
||||
end
|
||||
end
|
||||
l_node.set_author (response.user)
|
||||
-- new_node (response: NODE_RESPONSE; fd: WSF_FORM_DATA; a_node: detachable like new_node): CMS_PAGE
|
||||
-- -- <Precursor>
|
||||
-- local
|
||||
-- b: detachable READABLE_STRING_8
|
||||
-- f: detachable CONTENT_FORMAT
|
||||
-- l_node: detachable like new_node
|
||||
-- do
|
||||
-- l_node := a_node
|
||||
-- if attached fd.integer_item ("id") as l_id and then l_id > 0 then
|
||||
-- if l_node /= Void then
|
||||
-- check l_node.id = l_id end
|
||||
-- else
|
||||
-- if attached {like new_node} response.node_api.node (l_id) as n then
|
||||
-- l_node := n
|
||||
-- else
|
||||
-- -- FIXME: Error
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- if attached fd.string_item ("title") as l_title then
|
||||
-- if l_node = Void then
|
||||
-- l_node := content_type.new_node (Void)
|
||||
-- l_node.set_title (l_title)
|
||||
-- else
|
||||
-- l_node.set_title (l_title)
|
||||
-- end
|
||||
-- else
|
||||
-- if l_node = Void then
|
||||
-- l_node := content_type.new_node_with_title ("...", Void)
|
||||
-- end
|
||||
-- end
|
||||
-- l_node.set_author (response.user)
|
||||
|
||||
if attached fd.string_item ("body") as l_body then
|
||||
b := l_body
|
||||
end
|
||||
if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
f := f_format
|
||||
else
|
||||
f := response.api.formats.default_format
|
||||
end
|
||||
if b /= Void then
|
||||
l_node.set_content (b, Void, f.name)
|
||||
end
|
||||
Result := l_node
|
||||
end
|
||||
-- if attached fd.string_item ("body") as l_body then
|
||||
-- b := l_body
|
||||
-- end
|
||||
-- if attached fd.string_item ("format") as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- elseif a_node /= Void and then attached a_node.format as s_format and then attached response.api.format (s_format) as f_format then
|
||||
-- f := f_format
|
||||
-- else
|
||||
-- f := response.api.formats.default_format
|
||||
-- end
|
||||
-- if b /= Void then
|
||||
-- l_node.set_content (b, Void, f.name)
|
||||
-- end
|
||||
-- Result := l_node
|
||||
-- end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -59,6 +59,41 @@ feature -- Execution
|
||||
fd := f.last_data
|
||||
end
|
||||
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (l_node.title)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||
|
||||
b.append ("saved")
|
||||
else
|
||||
set_title ("Edit #" + l_node.id.out)
|
||||
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("Edit", "/node/" + l_node.id.out + "/edit"), primary_tabs)
|
||||
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
else
|
||||
b.append ("<h1>Access denied</h1>")
|
||||
end
|
||||
else
|
||||
set_title ("Unknown node")
|
||||
end
|
||||
elseif
|
||||
attached {WSF_STRING} request.path_parameter ("type") as p_type and then
|
||||
attached node_api.content_type (p_type.value) as l_type
|
||||
then
|
||||
if has_permission ("create " + l_type.name) then
|
||||
if attached l_type.new_node (Void) as l_node then
|
||||
f := edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, l_node, l_type, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
|
||||
set_title ("Edit #" + l_node.id.out)
|
||||
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make ("View", node_url (l_node)), primary_tabs)
|
||||
@@ -66,11 +101,12 @@ feature -- Execution
|
||||
|
||||
f.append_to_html (wsf_theme, b)
|
||||
else
|
||||
b.append ("<h1>Access denied</h1>")
|
||||
b.append ("<h1>Server error</h1>")
|
||||
end
|
||||
else
|
||||
set_title ("Unknown node")
|
||||
b.append ("<h1>Access denied</h1>")
|
||||
end
|
||||
|
||||
else
|
||||
set_title ("Create new content ...")
|
||||
b.append ("<ul id=%"content-types%">")
|
||||
@@ -140,10 +176,17 @@ feature -- Form
|
||||
end
|
||||
if a_node /= Void then
|
||||
l_node := a_node
|
||||
change_node (a_type, fd, a_node)
|
||||
s := "modified"
|
||||
if l_node.has_id then
|
||||
change_node (a_type, fd, a_node)
|
||||
s := "modified"
|
||||
else
|
||||
change_node (a_type, fd, a_node)
|
||||
l_node.set_author (user)
|
||||
s := "created"
|
||||
end
|
||||
else
|
||||
l_node := new_node (a_type, fd, Void)
|
||||
l_node.set_author (user)
|
||||
s := "created"
|
||||
end
|
||||
node_api.save_node (l_node)
|
||||
|
||||
@@ -129,10 +129,10 @@ feature -- HTTP Methods
|
||||
elseif l_nid > 0 then --| i.e: l_node = Void
|
||||
send_not_found (req, res)
|
||||
else
|
||||
send_bad_request (req, res)
|
||||
-- send_bad_request (req, res)
|
||||
-- FIXME: should not be accepted
|
||||
-- Factory
|
||||
-- create_new_node (req, res)
|
||||
create_new_node (req, res)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -145,6 +145,9 @@ feature -- HTTP Methods
|
||||
if req.path_info.ends_with_general ("/edit") then
|
||||
create edit_response.make (req, res, api, node_api)
|
||||
edit_response.execute
|
||||
elseif req.path_info.starts_with_general ("/node/add/") then
|
||||
create edit_response.make (req, res, api, node_api)
|
||||
edit_response.execute
|
||||
else
|
||||
to_implement ("Check user permissions!!!")
|
||||
if attached current_user (req) as l_user then
|
||||
@@ -293,14 +296,52 @@ feature {NONE} -- Node
|
||||
|
||||
create_new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
l_page: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
l_node: detachable CMS_NODE
|
||||
l_gen_page: GENERIC_VIEW_CMS_RESPONSE
|
||||
edit_response: NODE_FORM_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
if api.user_has_permission (current_user (req), "create node") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.execute
|
||||
if
|
||||
attached {WSF_STRING} req.path_parameter ("type") as p_type and then
|
||||
attached node_api.content_type (p_type.value) as ct
|
||||
then
|
||||
create edit_response.make (req, res, api, node_api)
|
||||
edit_response.execute
|
||||
-- create l_page.make (req, res, api)
|
||||
-- l_node := ct.new_node (Void)
|
||||
-- l_page.set_main_content (l_node.out)
|
||||
-- l_page.execute
|
||||
else
|
||||
send_access_denied (req, res)
|
||||
create l_gen_page.make (req, res, api)
|
||||
|
||||
create s.make_empty
|
||||
s.append ("<ul>")
|
||||
across
|
||||
node_api.content_types as ic
|
||||
loop
|
||||
if api.user_has_permission (current_user (req), "create " + ic.item.name) then
|
||||
s.append ("<li>")
|
||||
s.append (l_gen_page.link (ic.item.title, node_api.new_content_path (ic.item), Void))
|
||||
if attached ic.item.description as l_description then
|
||||
s.append ("<p class=%"description%">")
|
||||
s.append (l_gen_page.html_encoded (l_description))
|
||||
s.append ("</p>")
|
||||
end
|
||||
s.append ("</li>")
|
||||
end
|
||||
end
|
||||
s.append ("</ul>")
|
||||
l_gen_page.set_title ("Create new content ...")
|
||||
l_gen_page.set_main_content (s)
|
||||
l_gen_page.execute
|
||||
end
|
||||
-- if api.user_has_permission (current_user (req), "create node") then
|
||||
-- create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
-- l_page.execute
|
||||
-- else
|
||||
-- send_access_denied (req, res)
|
||||
-- end
|
||||
end
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
@@ -133,15 +133,15 @@ feature -- Access: router
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_node_handler.make (a_api, a_node_api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
l_methods.enable_post
|
||||
l_methods.lock
|
||||
a_router.handle_with_request_methods ("/node", l_node_handler, l_methods)
|
||||
a_router.handle_with_request_methods ("/node", l_node_handler, a_router.methods_get_post)
|
||||
a_router.handle_with_request_methods ("/node/", l_node_handler, a_router.methods_get_post)
|
||||
|
||||
create l_new_node_handler.make (a_api, a_node_api)
|
||||
a_router.handle_with_request_methods ("/node/new/{type}", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_by_type (?,?, "type", a_node_api)), a_router.methods_get)
|
||||
a_router.handle_with_request_methods ("/node/new", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_selection (?,?, a_node_api)), a_router.methods_get)
|
||||
a_router.handle_with_request_methods ("/node/add/{type}", l_new_node_handler, a_router.methods_get_post)
|
||||
a_router.handle_with_request_methods ("/node/new", l_new_node_handler, a_router.methods_get)
|
||||
|
||||
-- a_router.handle_with_request_methods ("/node/new/{type}", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_by_type (?,?, "type", a_node_api)), a_router.methods_get)
|
||||
-- a_router.handle_with_request_methods ("/node/new", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_node_creation_selection (?,?, a_node_api)), a_router.methods_get)
|
||||
|
||||
create l_edit_node_handler.make (a_api, a_node_api)
|
||||
a_router.handle_with_request_methods ("/node/{id}/edit", l_edit_node_handler, a_router.methods_get_post)
|
||||
@@ -149,6 +149,8 @@ feature -- Access: router
|
||||
create l_node_handler.make (a_api, a_node_api)
|
||||
a_router.handle_with_request_methods ("/node/{id}", l_node_handler, a_router.methods_get_put_delete + a_router.methods_get_post)
|
||||
|
||||
|
||||
|
||||
-- Nodes
|
||||
create l_nodes_handler.make (a_api, a_node_api)
|
||||
create l_methods
|
||||
@@ -261,51 +263,53 @@ feature -- Hooks
|
||||
do
|
||||
create lnk.make ("List of nodes", a_response.url ("/nodes", Void))
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
create lnk.make ("Create ..", a_response.url ("/node/", Void))
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
end
|
||||
|
||||
feature -- Handler
|
||||
--feature -- Handler
|
||||
|
||||
do_get_node_creation_selection (req: WSF_REQUEST; res: WSF_RESPONSE; a_node_api: CMS_NODE_API)
|
||||
local
|
||||
l_page: GENERIC_VIEW_CMS_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
create l_page.make (req, res, a_node_api.cms_api)
|
||||
-- do_get_node_creation_selection (req: WSF_REQUEST; res: WSF_RESPONSE; a_node_api: CMS_NODE_API)
|
||||
-- local
|
||||
-- l_page: GENERIC_VIEW_CMS_RESPONSE
|
||||
-- s: STRING
|
||||
-- do
|
||||
-- create l_page.make (req, res, a_node_api.cms_api)
|
||||
|
||||
create s.make_empty
|
||||
s.append ("<ul>")
|
||||
across
|
||||
a_node_api.content_types as ic
|
||||
loop
|
||||
s.append ("<li>")
|
||||
s.append (l_page.link (ic.item.title, a_node_api.new_content_path (ic.item), Void))
|
||||
if attached ic.item.description as l_description then
|
||||
s.append ("<p class=%"description%">")
|
||||
s.append (l_page.html_encoded (l_description))
|
||||
s.append ("</p>")
|
||||
end
|
||||
s.append ("</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
l_page.set_title ("Create new content ...")
|
||||
l_page.set_main_content (s)
|
||||
l_page.execute
|
||||
end
|
||||
-- create s.make_empty
|
||||
-- s.append ("<ul>")
|
||||
-- across
|
||||
-- a_node_api.content_types as ic
|
||||
-- loop
|
||||
-- s.append ("<li>")
|
||||
-- s.append (l_page.link (ic.item.title, a_node_api.new_content_path (ic.item), Void))
|
||||
-- if attached ic.item.description as l_description then
|
||||
-- s.append ("<p class=%"description%">")
|
||||
-- s.append (l_page.html_encoded (l_description))
|
||||
-- s.append ("</p>")
|
||||
-- end
|
||||
-- s.append ("</li>")
|
||||
-- end
|
||||
-- s.append ("</ul>")
|
||||
-- l_page.set_title ("Create new content ...")
|
||||
-- l_page.set_main_content (s)
|
||||
-- l_page.execute
|
||||
-- end
|
||||
|
||||
do_get_node_creation_by_type (req: WSF_REQUEST; res: WSF_RESPONSE; a_type_varname: READABLE_STRING_8; a_node_api: CMS_NODE_API)
|
||||
local
|
||||
l_page: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
l_node: detachable CMS_NODE
|
||||
do
|
||||
create l_page.make (req, res, a_node_api.cms_api)
|
||||
if
|
||||
attached {WSF_STRING} req.path_parameter (a_type_varname) as p_type and then
|
||||
attached a_node_api.content_type (p_type.value) as ct
|
||||
then
|
||||
l_node := ct.new_node (Void)
|
||||
l_page.set_main_content (l_node.out)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
-- do_get_node_creation_by_type (req: WSF_REQUEST; res: WSF_RESPONSE; a_type_varname: READABLE_STRING_8; a_node_api: CMS_NODE_API)
|
||||
-- local
|
||||
-- l_page: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
-- l_node: detachable CMS_NODE
|
||||
-- do
|
||||
-- create l_page.make (req, res, a_node_api.cms_api)
|
||||
-- if
|
||||
-- attached {WSF_STRING} req.path_parameter (a_type_varname) as p_type and then
|
||||
-- attached a_node_api.content_type (p_type.value) as ct
|
||||
-- then
|
||||
-- l_node := ct.new_node (Void)
|
||||
-- l_page.set_main_content (l_node.out)
|
||||
-- end
|
||||
-- l_page.execute
|
||||
-- end
|
||||
|
||||
end
|
||||
|
||||
@@ -231,7 +231,8 @@ feature {NONE} -- Implementation
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
sql_change (sql_update_node, l_parameters)
|
||||
if not error_handler.has_error then
|
||||
a_node.set_revision (a_node.revision + 1) -- FIXME: Should be incremented by one, in same transaction...but check!
|
||||
-- FIXED: FOR NOW no revision
|
||||
-- a_node.set_revision (a_node.revision + 1) -- FIXME: Should be incremented by one, in same transaction...but check!
|
||||
a_node.set_modification_date (now)
|
||||
end
|
||||
else
|
||||
@@ -273,7 +274,9 @@ feature {NONE} -- Queries
|
||||
sql_insert_node: STRING = "INSERT INTO nodes (revision, type, title, summary, content, format, publish, created, changed, author) VALUES (1, :type, :title, :summary, :content, :format, :publish, :created, :changed, :author);"
|
||||
-- SQL Insert to add a new node.
|
||||
|
||||
sql_update_node : STRING = "UPDATE nodes SET revision = revision + 1, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
|
||||
sql_update_node : STRING = "UPDATE nodes SET revision = revision, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, author=:author WHERE nid=:nid;"
|
||||
-- FIXME: for now no revision inc.!
|
||||
-- sql_update_node : STRING = "UPDATE nodes SET revision = revision + 1, type=:type, title=:title, summary=:summary, content=:content, format=:format, publish=:publish, changed=:changed, revision = revision + 1, author=:author WHERE nid=:nid;"
|
||||
-- SQL node.
|
||||
|
||||
sql_delete_node: STRING = "DELETE FROM nodes WHERE nid=:nid;"
|
||||
|
||||
@@ -147,25 +147,38 @@ feature -- Permissions system
|
||||
|
||||
feature -- Query: module
|
||||
|
||||
module (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE
|
||||
module (a_type: TYPE [detachable CMS_MODULE]): detachable CMS_MODULE
|
||||
-- Enabled module typed `a_type', if any.
|
||||
--| usage: if attached module ({FOO_MODULE}) as mod then ...
|
||||
local
|
||||
t: STRING_8
|
||||
l_type: TYPE [detachable CMS_MODULE]
|
||||
do
|
||||
t := a_type.name
|
||||
if t.starts_with ("!") then
|
||||
t.remove_head (1)
|
||||
end
|
||||
across
|
||||
setup.modules as ic
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
Result := ic.item
|
||||
if
|
||||
not Result.is_enabled
|
||||
or else Result.generating_type /~ a_type
|
||||
then
|
||||
if not Result.is_enabled then
|
||||
Result := Void
|
||||
else
|
||||
l_type := Result.generating_type
|
||||
if a_type ~ l_type then
|
||||
-- Found
|
||||
elseif t.same_string (l_type.name) then
|
||||
-- Found
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
end
|
||||
ensure
|
||||
Result /= Void implies (Result.is_enabled and Result.generating_type ~ a_type)
|
||||
Result /= Void implies (Result.is_enabled) -- and a_type.is_conforming_to (Result.generating_type))
|
||||
end
|
||||
|
||||
module_api (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE_API
|
||||
|
||||
@@ -1050,11 +1050,20 @@ feature {NONE} -- Execution
|
||||
h := page.header
|
||||
h.put_content_length (page.html.count)
|
||||
h.put_current_date
|
||||
h.put_header_object (header)
|
||||
if attached redirection as l_location then
|
||||
h.put_location (l_location)
|
||||
-- FIXME: find out if this is safe or not.
|
||||
if l_location.has_substring ("://") then
|
||||
-- h.put_location (l_location)
|
||||
response.redirect_now (l_location)
|
||||
else
|
||||
-- h.put_location (request.absolute_script_url (l_location))
|
||||
response.redirect_now (request.absolute_script_url (l_location))
|
||||
end
|
||||
else
|
||||
h.put_header_object (header)
|
||||
|
||||
response.send (page)
|
||||
end
|
||||
response.send (page)
|
||||
on_terminated
|
||||
end
|
||||
|
||||
|
||||
@@ -46,13 +46,22 @@ feature -- Status report
|
||||
elseif a_user = Void then
|
||||
Result := user_role_has_permission (anonymous_user_role, a_permission)
|
||||
else
|
||||
Result := user_role_has_permission (authenticated_user_role, a_permission)
|
||||
if not Result then
|
||||
Result := across user_roles (a_user) as ic some user_role_has_permission (ic.item, a_permission) end
|
||||
if is_admin_user (a_user) then
|
||||
Result := True
|
||||
else
|
||||
Result := user_role_has_permission (authenticated_user_role, a_permission)
|
||||
if not Result then
|
||||
Result := across user_roles (a_user) as ic some user_role_has_permission (ic.item, a_permission) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_admin_user (u: CMS_USER): BOOLEAN
|
||||
do
|
||||
Result := u.id = 1
|
||||
end
|
||||
|
||||
user_roles (a_user: CMS_USER): LIST [CMS_USER_ROLE]
|
||||
local
|
||||
l_roles: detachable LIST [CMS_USER_ROLE]
|
||||
|
||||
Reference in New Issue
Block a user