Implemented custom cms format, and associated administration pages.

Applied to existing filter and format.
Added embedded_video filter (initially contribute by Javier Velilla).
This commit is contained in:
Jocelyn Fiat
2017-03-30 11:58:44 +02:00
parent 134f876e62
commit 0ce7d11e52
20 changed files with 758 additions and 43 deletions

View File

@@ -42,6 +42,7 @@
<library name="cms_sitemap_module" location="..\..\modules\sitemap\sitemap-safe.ecf" readonly="false"/> <library name="cms_sitemap_module" location="..\..\modules\sitemap\sitemap-safe.ecf" readonly="false"/>
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/> <library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/>
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/> <library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
<library name="embedded_video_module" location="..\..\modules\embedded_video\embedded_video-safe.ecf" readonly="false"/>
<library name="cms_wikitext_module" location="..\..\modules\wikitext\wikitext-safe.ecf" readonly="false"/> <library name="cms_wikitext_module" location="..\..\modules\wikitext\wikitext-safe.ecf" readonly="false"/>
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false"/> <library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false"/>
<!-- <!--

View File

@@ -22,6 +22,7 @@
"taxonomy": { "location": "../../modules/taxonomy" }, "taxonomy": { "location": "../../modules/taxonomy" },
"files": { "location": "../../modules/files" }, "files": { "location": "../../modules/files" },
"custom_block": { "location": "../../modules/custom_block" }, "custom_block": { "location": "../../modules/custom_block" },
"embedded_video": { "location": "../../modules/embedded_video" },
"wikitext": { "location": "../../modules/wikitext" }, "wikitext": { "location": "../../modules/wikitext" },
"messaging": { "location": "../../modules/messaging" }, "messaging": { "location": "../../modules/messaging" },
"comments": { "location": "../../modules/comments" } "comments": { "location": "../../modules/comments" }

View File

@@ -76,6 +76,7 @@ feature -- CMS modules
-- Wiki -- Wiki
a_setup.register_module (create {WIKITEXT_MODULE}.make) a_setup.register_module (create {WIKITEXT_MODULE}.make)
a_setup.register_module (create {EMBEDDED_VIDEO_MODULE}.make)
-- Recent changes -- Recent changes
a_setup.register_module (create {CMS_RECENT_CHANGES_MODULE}.make) a_setup.register_module (create {CMS_RECENT_CHANGES_MODULE}.make)

View File

@@ -20,6 +20,7 @@
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/> <library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/> <library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization-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="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" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/> <library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>

View File

@@ -36,6 +36,7 @@ feature -- Security
Result.force ("clear blocks cache") Result.force ("clear blocks cache")
Result.force ("admin export") Result.force ("admin export")
Result.force ("admin import") Result.force ("admin import")
Result.force ("admin formats")
end end
feature {NONE} -- Router/administration feature {NONE} -- Router/administration
@@ -48,6 +49,7 @@ feature {NONE} -- Router/administration
l_modules_handler: CMS_ADMIN_MODULES_HANDLER l_modules_handler: CMS_ADMIN_MODULES_HANDLER
l_users_handler: CMS_ADMIN_USERS_HANDLER l_users_handler: CMS_ADMIN_USERS_HANDLER
l_roles_handler: CMS_ADMIN_ROLES_HANDLER l_roles_handler: CMS_ADMIN_ROLES_HANDLER
l_formats_handler: CMS_ADMIN_FORMATS_HANDLER
l_user_handler: CMS_USER_HANDLER l_user_handler: CMS_USER_HANDLER
l_role_handler: CMS_ROLE_HANDLER l_role_handler: CMS_ROLE_HANDLER
@@ -58,6 +60,7 @@ feature {NONE} -- Router/administration
l_admin_import_handler: CMS_ADMIN_IMPORT_HANDLER l_admin_import_handler: CMS_ADMIN_IMPORT_HANDLER
l_admin_path_alias_handler: CMS_ADMIN_PATH_ALIAS_HANDLER l_admin_path_alias_handler: CMS_ADMIN_PATH_ALIAS_HANDLER
l_uri_mapping: WSF_URI_MAPPING l_uri_mapping: WSF_URI_MAPPING
do do
create l_admin_handler.make (a_api) create l_admin_handler.make (a_api)
@@ -76,6 +79,13 @@ feature {NONE} -- Router/administration
create l_uri_mapping.make_trailing_slash_ignored ("/roles", l_roles_handler) create l_uri_mapping.make_trailing_slash_ignored ("/roles", l_roles_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post) a_router.map (l_uri_mapping, a_router.methods_get_post)
create l_formats_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/formats", l_formats_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post)
create l_uri_mapping.make_trailing_slash_ignored ("/formats", l_formats_handler)
a_router.handle ("/formats/{format-id}", l_formats_handler, a_router.methods_get_post)
a_router.handle ("/formats/{format-id}/add", l_formats_handler, a_router.methods_get_post)
create l_admin_logs_handler.make (a_api) create l_admin_logs_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/logs", l_admin_logs_handler) create l_uri_mapping.make_trailing_slash_ignored ("/logs", l_admin_logs_handler)
a_router.map (l_uri_mapping, a_router.methods_get) a_router.map (l_uri_mapping, a_router.methods_get)
@@ -108,6 +118,7 @@ feature {NONE} -- Router/administration
a_router.handle ("/role/{id}", l_role_handler, a_router.methods_get) a_router.handle ("/role/{id}", l_role_handler, a_router.methods_get)
a_router.handle ("/role/{id}/edit", l_role_handler, a_router.methods_get_post) a_router.handle ("/role/{id}/edit", l_role_handler, a_router.methods_get_post)
a_router.handle ("/role/{id}/delete", l_role_handler, a_router.methods_get_post) a_router.handle ("/role/{id}/delete", l_role_handler, a_router.methods_get_post)
end end
feature -- Hooks feature -- Hooks
@@ -137,6 +148,10 @@ feature -- Hooks
create lnk.make ("Module", l_api.administration_path_location ("modules")) create lnk.make ("Module", l_api.administration_path_location ("modules"))
lnk.set_permission_arguments (<<"manage module">>) lnk.set_permission_arguments (<<"manage module">>)
admin_lnk.extend (lnk)
create lnk.make ("Formats", l_api.administration_path_location ("formats"))
lnk.set_permission_arguments (<<"admin formats">>)
admin_lnk.extend (lnk) admin_lnk.extend (lnk)
-- Per module cache permission! -- Per module cache permission!

View File

@@ -60,12 +60,6 @@ feature {CMS_API} -- Module Initialization
node_api := l_node_api node_api := l_node_api
-- Depends on {CMS_NODE_MODULE} -- Depends on {CMS_NODE_MODULE}
--| For now, add all available formats to content type `ct'.
across
api.formats as ic
loop
ct.extend_format (ic.item)
end
l_node_api.add_node_type (ct) l_node_api.add_node_type (ct)
l_node_api.add_node_type_webform_manager (create {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}.make (ct, l_node_api)) l_node_api.add_node_type_webform_manager (create {CMS_BLOG_NODE_TYPE_WEBFORM_MANAGER}.make (ct, l_node_api))
end end

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="embedded_video" uuid="1469E34C-98EE-4E39-BC13-24A0D93A7EC0" library_target="embedded_video">
<target name="embedded_video">
<root all_classes="true"/>
<option warning="true" void_safety="all">
</option>
<setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,61 @@
note
description: "[
Module that allows you to embed videos from YouTube and Vimeo in a web page.
]"
date: "$Date: 2015-07-16 15:57:08 +0200 (jeu., 16 juil. 2015) $"
revision: "$Revision: 97722 $"
class
EMBEDDED_VIDEO_MODULE
inherit
CMS_MODULE
redefine
initialize
end
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
REFACTORING_HELPER
create
make
feature {NONE} -- Initialization
make
-- Create current module
do
version := "1.0"
description := "Embedded video module"
package := "filters"
end
feature -- Access
name: STRING = "embedded_video"
-- <Precursor>
feature {CMS_API} -- Module Initialization
initialize (api: CMS_API)
-- <Precursor>
do
Precursor {CMS_MODULE} (api)
api.content_filters.extend (create {VIDEO_CONTENT_FILTER})
-- f := api.new_format ("video_html", "Video HTML content", <<{VIDEO_CONTENT_FILTER}.name>>)
-- api.formats.extend (f)
end
feature -- Router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
-- Router configuration.
do
end
end

View File

@@ -0,0 +1,182 @@
note
description: "[
Quick syntax:
[video:url]
Full syntax:
[video:url width:X height:Y]
]"
date: "$Date: 2015-07-18 13:53:56 +0200 (sam., 18 juil. 2015) $"
revision: "$Revision: 97737 $"
class
VIDEO_CONTENT_FILTER
inherit
CONTENT_FILTER
redefine
help,
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
width := 420
height := 315
end
feature -- Access
name: STRING_8 = "video"
title: STRING_8 = "Embedded video"
description: STRING_8 = "Embed any video using pattern [video:url width:X height:Y], width and height are optionals."
help: STRING = "Embed video using the following pattern: [video:url width:X height:Y], width and height are optionals."
feature -- Conversion
filter (a_text: STRING_8)
-- [video:url width:X height:Y]
local
l_new: detachable STRING
i,p,q,diff: INTEGER
do
from
i := 1
until
i > a_text.count
loop
p := a_text.substring_index ("[video:", i)
if p > 0 then
q := a_text.index_of (']', p + 1)
l_new := to_embedded_video_code (a_text, p, q)
if l_new /= Void then
diff := l_new.count - (q - p + 1)
i := i + diff
a_text.replace_substring (l_new, p, q)
else
i := q + 1
end
else
i := a_text.count
end
i := i + 1
end
end
to_embedded_video_code (a_text: STRING_8; a_lower, a_upper: INTEGER): detachable STRING
require
a_lower < a_upper
a_text.substring (a_lower, a_lower + 7).same_string ("[video:")
a_text.ends_with_general ("]")
local
i,j,n: INTEGER
s,k,v: STRING_8
l_url: STRING_8
l_width, l_height: detachable STRING
do
s := a_text.substring (a_lower + 1, a_upper - 1)
s.left_adjust
i := next_space_position (s, 1)
if i > 0 then
l_url := s.head (i - 1)
s.remove_head (i)
s.left_adjust
from
n := s.count
i := 1
until
i > n
loop
j := s.index_of (':', i)
if j > 0 then
k := s.head (j - 1)
s.remove_head (j)
s.left_adjust
i := 1
n := s.count
j := next_space_position (s, 1)
if j > 0 then
v := s.head (j - 1)
s.remove_head (j)
s.left_adjust
else
v := s.substring (i, n)
s.wipe_out
end
n := s.count
i := 1
if k.is_case_insensitive_equal ("width") then
l_width := v
elseif k.is_case_insensitive_equal ("height") then
l_height := v
else
check supported: False end
end
else
i := n + 1
end
end
else
s.remove_head (6)
l_url := s
end
if not l_url.is_whitespace then
create Result.make_from_string ("<iframe src=%"")
Result.append (l_url)
Result.append_character ('%"')
if l_width = Void then
if width > 0 then
l_width := width.out
end
end
if l_height = Void then
if height > 0 then
l_height := height.out
end
end
if l_width /= Void then
Result.append (" width=%"")
Result.append (l_width)
Result.append_character ('%"')
end
if l_height /= Void then
Result.append (" height=%"")
Result.append (l_height)
Result.append_character ('%"')
end
Result.append ("frameborder=%"0%" allowfullscreen></iframe>")
end
end
next_space_position (a_text: STRING; a_start_index: INTEGER): INTEGER
local
n: INTEGER
do
from
Result := a_start_index
n := a_text.count
until
a_text[Result].is_space or Result > n
loop
Result := Result + 1
end
if Result > n then
Result := 0
end
end
feature {NONE} -- Implementation
width: INTEGER;
-- Specifies the width of an <iframe> in pixels.
height: INTEGER
-- Specifies the height of an <iframe> in pixels.
end

View File

@@ -0,0 +1,34 @@
note
description: "Summary description for {VIDEO_HTML_CONTENT_FORMAT}."
author: ""
date: "$Date: 2015-07-10 13:38:10 +0200 (ven., 10 juil. 2015) $"
revision: "$Revision: 97687 $"
class
VIDEO_HTML_CONTENT_FORMAT
inherit
CONTENT_FORMAT
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create filters.make (0)
filters.force (create {VIDEO_CONTENT_FILTER})
end
feature -- Access
name: STRING = "video_html"
title: STRING_8 = "Video HTML content"
filters: ARRAYED_LIST [CONTENT_FILTER]
end

View File

@@ -0,0 +1,183 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date: 2015-07-10 13:38:10 +0200 (ven., 10 juil. 2015) $"
revision: "$Revision: 97687 $"
testing: "type/manual"
class
TEST_CONTENT_FILTER_SET
inherit
EQA_TEST_SET
feature -- Test routines
test_video_filter
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[video:https://www.youtube.com/embed/jBMOSSnCMCk]"
expected_text := "<iframe width=%"420%" height=%"315%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_2
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ video : https://www.youtube.com/embed/jBMOSSnCMCk ]"
expected_text := "<iframe width=%"420%" height=%"315%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_3
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ video :https://www.youtube.com/embed/jBMOSSnCMCk ]"
expected_text := "<iframe width=%"420%" height=%"315%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_4
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ video :https://www.youtube.com/embed/jBMOSSnCMCk height:425]"
expected_text := "<iframe width=%"420%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_5
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ video :https://www.youtube.com/embed/jBMOSSnCMCk height : 425]"
expected_text := "<iframe width=%"420%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_6
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ video :https://www.youtube.com/embed/jBMOSSnCMCk height : 425 width: 425]"
expected_text := "<iframe width=%"425%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_7
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[video:https://www.youtube.com/embed/jBMOSSnCMCk height:425 width:425]"
expected_text := "<iframe width=%"425%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_8
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[height:425 width:425 video:https://www.youtube.com/embed/jBMOSSnCMCk ]"
expected_text := "<iframe width=%"425%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_9
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ width:425 video:https://www.youtube.com/embed/jBMOSSnCMCk height:425]"
expected_text := "<iframe width=%"425%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_10
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[ wrong:425 video:https://www.youtube.com/embed/jBMOSSnCMCk height:425]"
expected_text := "<iframe width=%"420%" height=%"425%"%Nsrc=%"https://www.youtube.com/embed/jBMOSSnCMCk%">%N</iframe>"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
test_video_filter_11
-- New test routine
local
f: VIDEO_CONTENT_FILTER
text: STRING
expected_text: STRING
do
text := "[wrong hello:1020 ]"
expected_text := "[wrong hello:1020 ]"
create f
f.filter (text)
assert ("expected iframe with video", text.same_string (expected_text))
end
end

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<redirection xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" uuid="BD491995-C14C-4413-B09A-C1B4EDDA3116" message="Obsolete: use testing.ecf !" location="testing.ecf">
</redirection>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="embedded_video_testing" uuid="BD491995-C14C-4413-B09A-C1B4EDDA3116">
<target name="embedded_video_testing">
<root class="ANY" feature="default_create"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true">
</option>
<capability>
<concurrency use="none"/>
</capability>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="embeded_module" location="..\video.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
<tests name="src" location=".\"/>
</target>
</system>

View File

@@ -54,12 +54,6 @@ feature {NONE} -- Initialization
-- Initialize node content types. -- Initialize node content types.
create ct create ct
page_content_type := ct page_content_type := ct
--| For now, add all available formats to content type `ct'.
across
cms_api.formats as ic
loop
ct.extend_format (ic.item)
end
node_api.add_node_type (ct) node_api.add_node_type (ct)
node_api.add_node_type_webform_manager (create {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}.make (ct, Current)) node_api.add_node_type_webform_manager (create {CMS_PAGE_NODE_TYPE_WEBFORM_MANAGER}.make (ct, Current))
end end

View File

@@ -39,18 +39,12 @@ feature {CMS_API} -- Module Initialization
initialize (api: CMS_API) initialize (api: CMS_API)
-- <Precursor> -- <Precursor>
local
f: CMS_FORMAT
do do
Precursor (api) Precursor (api)
create f.make_from_format (create {WIKITEXT_FORMAT}) api.content_filters.extend (create {WIKITEXT_FILTER})
api.formats.extend (f) if api.format ({WIKITEXT_FORMAT}.name) = Void then
-- FIXME!!! api.formats.extend (api.new_format ("wikitext", "Wikitext rendered as HTML", <<{WIKITEXT_FILTER}.name>>))
across
api.content_types as ic
loop
ic.item.extend_format (f)
end end
end end

View File

@@ -10,6 +10,8 @@ class
inherit inherit
CONTENT_FORMAT CONTENT_FORMAT
DEBUG_OUTPUT
create create
make, make,
make_from_format make_from_format
@@ -55,6 +57,27 @@ feature -- Access
end end
end end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
create Result.make_from_string (name)
if not title.same_string (name) then
Result.append_character (' ')
Result.append_character ('"')
Result.append (title)
Result.append_character ('"')
end
Result.append_character (' ')
across
filters as ic
loop
Result.append_character ('+')
Result.append (ic.item.name)
end
end
feature -- Element change feature -- Element change
set_title (a_title: detachable READABLE_STRING_8) set_title (a_title: detachable READABLE_STRING_8)
@@ -108,6 +131,6 @@ feature -- Element change
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -36,8 +36,33 @@ feature -- Access
end end
end end
is_empty: BOOLEAN
do
Result := count = 0
end
count: INTEGER
do
Result := items.count
end
feature -- Element change feature -- Element change
remove (a_name: READABLE_STRING_GENERAL)
do
from
items.start
until
items.after
loop
if a_name.is_case_insensitive_equal (items.item.name) then
items.remove
else
items.forth
end
end
end
extend (f: CMS_FORMAT) extend (f: CMS_FORMAT)
-- Add format `f' to available formats. -- Add format `f' to available formats.
do do
@@ -46,6 +71,12 @@ feature -- Element change
has_format: item (f.name) = f has_format: item (f.name) = f
end end
wipe_out
-- Wipe out the items.
do
items.wipe_out
end
feature -- Access feature -- Access
new_cursor: ITERATION_CURSOR [CMS_FORMAT] new_cursor: ITERATION_CURSOR [CMS_FORMAT]
@@ -79,7 +110,7 @@ invariant
items /= Void items /= Void
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -54,11 +54,12 @@ feature {NONE} -- Initialize
s := setup.administration_base_path s := setup.administration_base_path
administration_base_path_location := s.shared_substring (2, s.count) administration_base_path_location := s.shared_substring (2, s.count)
-- Initialize formats.
initialize_formats
-- Initialize contents. -- Initialize contents.
initialize_content_types initialize_content_types
-- Initialize filters and formats.
initialize_content_filters_and_formats
-- Initialize storage. -- Initialize storage.
if attached setup.storage (error_handler) as l_storage then if attached setup.storage (error_handler) as l_storage then
storage := l_storage storage := l_storage
@@ -109,6 +110,7 @@ feature {NONE} -- Initialize
end end
-- hooks initialization, is done after site/admin switch. -- hooks initialization, is done after site/admin switch.
-- See `initialize_execution`
end end
initialize_site_url initialize_site_url
@@ -147,21 +149,157 @@ feature {NONE} -- Initialize
create content_type_webform_managers.make (1) create content_type_webform_managers.make (1)
end end
initialize_formats initialize_content_filters_and_formats
-- Initialize content formats. -- Initialize content filters and formats.
local local
f: CMS_FORMAT l_filters: like content_filters
do do
-- Initialize built-in content filters
create l_filters.make (4)
content_filters := l_filters
l_filters.extend (create {HTML_TO_TEXT_CONTENT_FILTER})
l_filters.extend (create {LINE_BREAK_TO_HTML_CONTENT_FILTER})
l_filters.extend (create {URL_CONTENT_FILTER})
l_filters.extend (create {HTML_CONTENT_FILTER})
-- Initialize built-in formats -- Initialize built-in formats
create formats.make (4) create formats.make (4)
create f.make_from_format (create {PLAIN_TEXT_CONTENT_FORMAT}) end
formats.extend (f)
create f.make_from_format (create {FILTERED_HTML_CONTENT_FORMAT}) setup_formats
formats.extend (f) -- Initialize content filters and formats.
create f.make_from_format (create {FULL_HTML_CONTENT_FORMAT}) local
formats.extend (f) l_formats: like formats
create f.make ("cms_editor", "CMS HTML content") do
formats.extend (f) load_formats
l_formats := formats
if l_formats.count = 0 then
-- Setup built-in formats
-- plain_text: html_to_text + line_break_converter
l_formats.extend (new_format ("plain_text", "Plain text", <<{HTML_TO_TEXT_CONTENT_FILTER}.name, {LINE_BREAK_TO_HTML_CONTENT_FILTER}.name>>))
-- full_html: url
l_formats.extend (new_format ("full_html", "Full HTML", <<{URL_CONTENT_FILTER}.name>>))
-- filtered_html: url + html_filter + line_break_converter
l_formats.extend (new_format ("filtered_html", "Filtered HTML", <<{URL_CONTENT_FILTER}.name, {HTML_CONTENT_FILTER}.name, {LINE_BREAK_TO_HTML_CONTENT_FILTER}.name>>))
-- CMS Editor!
l_formats.extend (new_format ("cms_editor", "CMS HTML content", Void))
save_formats
end
end
feature {CMS_API_ACCESS} -- CMS Formats management
load_formats
local
f: CMS_FORMAT
jp: JSON_PARSER
s: STRING_32
l_name, l_title: READABLE_STRING_8
do
formats.wipe_out
if
attached storage.custom_value ("cms.formats", "api-formats") as v_formats and then
v_formats.is_valid_as_string_8
then
create jp.make_with_string (v_formats.to_string_8)
jp.parse_content
if jp.is_parsed and then jp.is_valid and then attached jp.parsed_json_object as j_formats then
-- { "plain_text": { "title": "Plain text", "filters": "plain_text+foobar+toto"}, ...}
across
j_formats as ic
loop
if attached {JSON_OBJECT} ic.item as j_format then
l_name := ic.key.unescaped_string_8
if attached {JSON_STRING} j_format.item ("title") as j_title then
l_title := j_title.unescaped_string_8
else
l_title := l_name
end
if attached {JSON_STRING} j_format.item ("filters") as j_filters then
s := j_filters.unescaped_string_32
f := new_format (l_name, l_title, s.split ('+'))
else
f := new_format (l_name, l_title, Void)
end
formats.extend (f)
if attached {JSON_STRING} j_format.item ("types") as j_types then
s := j_types.unescaped_string_32
across
s.split ('+') as s_ic
loop
if attached content_type (s_ic.item) as ct then
ct.extend_format (f)
end
end
end
end
end
end
end
end
save_formats
-- Save `formats`.
local
f: CMS_FORMAT
jp: JSON_PARSER
cfg: JSON_CONFIG
j,ji: JSON_OBJECT
s: STRING_32
l_name, l_title: READABLE_STRING_8
ct: CMS_CONTENT_TYPE
do
-- { "plain_text": { "title": "Plain text", "filters": "plain_text+foobar+toto"}, ...}
create j.make_empty
across
formats as ic
loop
f := ic.item
create ji.make
ji.put_string (f.title, "title")
create s.make_empty
across
f.filters as f_ic
loop
if not s.is_empty then
s.append ("+")
end
s.append (f_ic.item.name)
end
ji.put_string (s, "filters")
create s.make_empty
across
content_types as ct_ic
loop
ct := ct_ic.item
if ct.has_format (f.name) then
if not s.is_empty then
s.append ("+")
end
s.append (ct.name)
end
end
ji.put_string (s, "types")
j.put (ji, f.name)
end
storage.set_custom_value ("cms.formats", j.representation, "api-formats")
end
feature -- Execution initialization
initialize_execution
do
setup_hooks
setup_formats
end end
feature {CMS_ACCESS} -- Module management feature {CMS_ACCESS} -- Module management
@@ -437,17 +575,35 @@ feature -- Content type webform
end end
end end
feature -- Formats feature -- Filters and Formats
content_filters: CMS_CONTENT_FILTERS
-- Available content filters.
formats: CMS_FORMATS formats: CMS_FORMATS
-- Available content formats. -- Available content formats.
format (a_format_name: detachable READABLE_STRING_GENERAL): detachable CONTENT_FORMAT format (a_format_name: detachable READABLE_STRING_GENERAL): detachable CMS_FORMAT
-- Content format name `a_format_name' if any. -- Content format name `a_format_name' if any.
do do
Result := formats.item (a_format_name) Result := formats.item (a_format_name)
end end
new_format (a_name: READABLE_STRING_8; a_title: READABLE_STRING_8; a_filter_names: detachable ITERABLE [READABLE_STRING_GENERAL]): CMS_FORMAT
-- New cms content format named `a_name`, with `a_title`, and composed from `a_filter_names`.
do
create Result.make (a_name, a_title)
if a_filter_names /= Void then
across
a_filter_names as ic
loop
if attached content_filters.item (ic.item) as f then
Result.add_filter (f)
end
end
end
end
feature -- Status Report feature -- Status Report
has_error: BOOLEAN has_error: BOOLEAN

View File

@@ -161,7 +161,7 @@ feature -- Settings: router
-- Configure root of api handler. -- Configure root of api handler.
l_router.set_base_url (l_api.administration_path (Void)) l_router.set_base_url (l_api.administration_path (Void))
-- Include routes from modules. -- Include routes from modules.
across across
modules as ic modules as ic
@@ -244,7 +244,7 @@ feature -- Request execution
initialize_site_execution initialize_site_execution
-- Initialize for site execution. -- Initialize for site execution.
do do
api.setup_hooks api.initialize_execution
setup_router setup_router
end end
@@ -252,7 +252,7 @@ feature -- Request execution
-- Initialize for administration execution. -- Initialize for administration execution.
do do
api.switch_to_administration_mode api.switch_to_administration_mode
api.setup_hooks api.initialize_execution
setup_router_for_administration setup_router_for_administration
end end

View File

@@ -31,12 +31,18 @@ feature -- Access
feature -- Access feature -- Access
has_format (a_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is Current content type supporting format `a_name`?
do
Result := format (a_name) /= Void
end
available_formats: LIST [CONTENT_FORMAT] available_formats: LIST [CONTENT_FORMAT]
-- Available formats for Current type. -- Available formats for Current type.
deferred deferred
end end
format (a_name: READABLE_STRING_8): detachable CONTENT_FORMAT format (a_name: READABLE_STRING_GENERAL): detachable CONTENT_FORMAT
-- Format named `a_name', if available. -- Format named `a_name', if available.
do do
across across
@@ -87,6 +93,6 @@ feature -- Element change
end end
note note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end