diff --git a/library/configuration/src/json_config.e b/library/configuration/src/json_config.e
index 339c38f..8e3a5d9 100644
--- a/library/configuration/src/json_config.e
+++ b/library/configuration/src/json_config.e
@@ -148,7 +148,9 @@ feature -- Access
-- `k' can be a single name such as "foo",
-- or a qualified name such as "foo.bar" (assuming that "foo" is associated with a JSON object).
do
- if attached json_value as obj then
+ if k.is_empty then
+ Result := json_value
+ elseif attached json_value as obj then
Result := object_json_value (obj, k.to_string_32)
end
end
diff --git a/modules/blog/handler/blog_handler.e b/modules/blog/handler/blog_handler.e
index 731a58e..d483133 100644
--- a/modules/blog/handler/blog_handler.e
+++ b/modules/blog/handler/blog_handler.e
@@ -156,6 +156,7 @@ feature -- HTML Output
local
n: CMS_NODE
lnk: CMS_LOCAL_LINK
+ l_hide: BOOLEAN
do
-- Output the title. If more than one page, also output the current page number
append_page_title_html_to (page, a_output)
@@ -169,25 +170,42 @@ feature -- HTML Output
posts as ic
loop
n := ic.item
- lnk := blog_api.node_api.node_link (n)
- a_output.append ("
")
+ l_hide := not n.is_published
+ if l_hide then
+ if
+ attached api.user as u
+ then
+ if api.user_api.is_admin_user (u) then
+ l_hide := False
+ else
+ l_hide := not u.same_as (n.author)
+ end
+ end
+ end
+ if not l_hide then
+ lnk := blog_api.node_api.node_link (n)
+ a_output.append ("
")
- -- Output the creation date
- append_creation_date_html_to (n, a_output)
+ if not n.is_published then
+ a_output.append ("
This entry is not yet published!
")
+ end
+ -- Output the creation date
+ append_creation_date_html_to (n, a_output)
- -- Output the author of the post
- append_author_html_to (n, page, a_output)
+ -- Output the author of the post
+ append_author_html_to (n, page, a_output)
- -- Output the title of the post as a link (to the detail page)
- append_title_html_to (n, page, a_output)
+ -- Output the title of the post as a link (to the detail page)
+ append_title_html_to (n, page, a_output)
- -- Output associated tags.
- append_taxonomy_html_to (n, page, a_output)
+ -- Output associated tags.
+ append_taxonomy_html_to (n, page, a_output)
- -- Output the summary of the post and a more link to the detail page
- append_summary_html_to (n, page, a_output)
+ -- Output the summary of the post and a more link to the detail page
+ append_summary_html_to (n, page, a_output)
- a_output.append ("
%N")
+ a_output.append ("%N")
+ end
end
-- End of post list
diff --git a/modules/embedded_video/src/video_content_filter.e b/modules/embedded_video/src/video_content_filter.e
index c445aed..3a28e8d 100644
--- a/modules/embedded_video/src/video_content_filter.e
+++ b/modules/embedded_video/src/video_content_filter.e
@@ -70,10 +70,10 @@ feature -- Settings change
feature -- Conversion
- filter (a_text: STRING_8)
+ filter (a_text: STRING_GENERAL)
-- [video:url width:X height:Y]
local
- l_new: detachable STRING
+ l_new: detachable STRING_GENERAL
i,p,q,diff: INTEGER
do
from
@@ -88,7 +88,7 @@ feature -- Conversion
if l_new /= Void then
diff := l_new.count - (q - p + 1)
i := i + diff
- a_text.replace_substring (l_new, p, q)
+ replace_substring (a_text, l_new, p, q)
else
i := q + 1
end
@@ -99,23 +99,23 @@ feature -- Conversion
end
end
- to_embedded_video_code (a_text: STRING_8; a_lower, a_upper: INTEGER): detachable STRING
+ to_embedded_video_code (a_text: STRING_GENERAL; a_lower, a_upper: INTEGER): detachable STRING_GENERAL
require
a_lower < a_upper
a_text.substring (a_lower, a_lower + 7).same_string ("[video:")
- a_text.ends_with_general ("]")
+ a_text.ends_with ("]")
local
i,j,n: INTEGER
- s,k,v: STRING_8
- l_url, l_att: STRING_8
- l_width, l_height, l_extra: detachable STRING
+ s,k,v: STRING_GENERAL
+ l_url, l_att: STRING_GENERAL
+ l_width, l_height, l_extra: detachable STRING_GENERAL
do
s := a_text.substring (a_lower + 7, 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)
+ remove_head (s, i)
s.left_adjust
from
n := s.count
@@ -128,7 +128,7 @@ feature -- Conversion
k := s.head (j - 1)
k.left_adjust
k.right_adjust
- s.remove_head (j)
+ remove_head (s, j)
s.left_adjust
i := 1
n := s.count
@@ -137,13 +137,13 @@ feature -- Conversion
v := s.head (j - 1)
v.left_adjust
v.right_adjust
- s.remove_head (j)
+ remove_head (s, j)
s.left_adjust
else
v := s.substring (i, n)
v.left_adjust
v.right_adjust
- s.wipe_out
+ wipe_out (s)
end
n := s.count
i := 1
@@ -177,40 +177,46 @@ feature -- Conversion
l_height := default_height.out
end
end
- create l_att.make_empty
+ create {STRING_8} l_att.make_empty
if l_width /= Void then
if not l_att.is_empty then
- l_att.append_character (' ')
+ append_character (l_att, ' ')
end
l_att.append ("width=%"")
l_att.append (l_width)
- l_att.append_character ('%"')
+ append_character (l_att, '%"')
end
if l_height /= Void then
if not l_att.is_empty then
- l_att.append_character (' ')
+ append_character (l_att, ' ')
end
l_att.append ("height=%"")
l_att.append (l_height)
- l_att.append_character ('%"')
+ append_character (l_att, '%"')
end
if l_extra /= Void and then not l_extra.is_empty then
if not l_att.is_empty and not l_extra[1].is_space then
- l_att.append_character (' ')
+ append_character (l_att, ' ')
end
l_att.append (l_extra)
end
- if attached template as tpl then
- create Result.make_from_string (tpl)
- Result.replace_substring_all ("$url", l_url)
- Result.replace_substring_all ("$att", l_att)
+ if attached {STRING_8} a_text then
+ create {STRING_8} Result.make_empty
else
- create Result.make_from_string ("")
@@ -218,7 +224,7 @@ feature -- Conversion
end
end
- next_space_position (a_text: STRING; a_start_index: INTEGER): INTEGER
+ next_space_position (a_text: READABLE_STRING_GENERAL; a_start_index: INTEGER): INTEGER
local
n: INTEGER
do
@@ -235,23 +241,52 @@ feature -- Conversion
end
end
- next_non_space_position (a_text: STRING; a_start_index: INTEGER): INTEGER
- local
- n: INTEGER
+feature {NONE} -- Implementation
+
+ replace_substring (a_text: STRING_GENERAL; s: READABLE_STRING_GENERAL; start_index, end_index: INTEGER_32)
do
- from
- Result := a_start_index
- n := a_text.count
- until
- not a_text[Result].is_space or Result > n
- loop
- Result := Result + 1
- end
- if Result > n then
- Result := 0
+ if attached {STRING_8} a_text as s8 then
+ s8.replace_substring (s.to_string_8, start_index, end_index)
+ elseif attached {STRING_32} s as s32 then
+ s32.replace_substring (s.as_string_32, start_index, end_index)
+ end
+ end
+
+ replace_substring_all (s: STRING_GENERAL; a_old: READABLE_STRING_8; a_new: STRING_GENERAL)
+ do
+ if attached {STRING_8} s as s8 then
+ s8.replace_substring_all (a_old, a_new.to_string_8)
+ elseif attached {STRING_32} s as s32 then
+ s32.replace_substring_all (a_old, a_new)
+ end
+ end
+
+ append_character (s: STRING_GENERAL; c: CHARACTER)
+ do
+ s.append_code (c.natural_32_code)
+ end
+
+ wipe_out (s: STRING_GENERAL)
+ do
+ if attached {STRING_8} s as s8 then
+ s8.wipe_out
+ elseif attached {STRING_32} s as s32 then
+ s32.wipe_out
+ else
+ s.keep_tail (0)
+ end
+ end
+
+ remove_head (s: STRING_GENERAL; n: INTEGER)
+ do
+ if attached {STRING_8} s as s8 then
+ s8.remove_head (n)
+ elseif attached {STRING_32} s as s32 then
+ s32.remove_head (n)
+ else
+ s.keep_tail (s.count - n)
end
end
-invariant
end
diff --git a/modules/embedded_video/test/test_content_filter_set.e b/modules/embedded_video/test/test_content_filter_set.e
index a9073a0..6a44f4a 100644
--- a/modules/embedded_video/test/test_content_filter_set.e
+++ b/modules/embedded_video/test/test_content_filter_set.e
@@ -29,6 +29,30 @@ feature -- Test routines
assert ("expected iframe with video", text.same_string (expected_text))
end
+ test_video_filter_01_multi
+ -- New test routine
+ local
+ f: VIDEO_CONTENT_FILTER
+ text: STRING
+ expected_text: STRING
+ do
+ text := "[
+ [video:https://www.youtube.com/embed/jBMOSSnCMCk]
+ and [video:https://www.youtube.com/embed/jBMOSSnCMCk]
+ and [video:https://www.youtube.com/embed/jBMOSSnCMCk]
+ done
+ ]"
+ expected_text := "[
+
+ and
+ and
+ done
+ ]"
+ create f
+ f.filter (text)
+ assert ("expected iframe with video", text.same_string (expected_text))
+ end
+
test_video_filter_02
-- New test routine
diff --git a/modules/node/handler/cms_node_type_webform_manager_i.e b/modules/node/handler/cms_node_type_webform_manager_i.e
index 78337f7..9eecd96 100644
--- a/modules/node/handler/cms_node_type_webform_manager_i.e
+++ b/modules/node/handler/cms_node_type_webform_manager_i.e
@@ -88,6 +88,11 @@ feature -- Output
a_response.set_value (a_node, "node")
a_response.set_value (a_node.content_type, "optional_content_type")
create s.make_empty
+ if a_node.is_not_published then
+ a_response.add_warning_message ("This node is NOT published!")
+ elseif a_node.is_trashed then
+ a_response.add_warning_message ("This node is in the TRASH!")
+ end
append_content_as_html_to (a_node, False, s, a_response)
a_response.set_main_content (s)
end
diff --git a/modules/node/handler/node_form_response.e b/modules/node/handler/node_form_response.e
index 2389be8..c554ef8 100644
--- a/modules/node/handler/node_form_response.e
+++ b/modules/node/handler/node_form_response.e
@@ -254,15 +254,25 @@ feature -- Form
edit_form_submit (fd: WSF_FORM_DATA; a_node: detachable CMS_NODE; a_type: CMS_NODE_TYPE [CMS_NODE]; b: STRING)
local
- l_preview: BOOLEAN
+ l_preview, l_op_save, l_op_publish, l_op_unpublish: BOOLEAN
l_node: detachable CMS_NODE
s: STRING
l_node_path: READABLE_STRING_8
l_path_alias, l_existing_path_alias, l_auto_path_alias: detachable READABLE_STRING_8
do
- fixme ("Refactor code per operacion: Preview, Save")
- l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Preview")
+ fixme ("Refactor code per operation: Preview, Save/Publish/UnPublish")
+ l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string (preview_submit_label)
if not l_preview then
+ l_op_save := True
+ if attached {WSF_STRING} fd.item ("op") as l_op then
+ if l_op.same_string (publish_submit_label) then
+ l_op_publish := True
+ elseif l_op.same_string (unpublish_submit_label) then
+ l_op_unpublish := True
+ else
+ check l_op.same_string (save_submit_label) end
+ end
+ end
debug ("cms")
across
fd as c
@@ -289,8 +299,13 @@ feature -- Form
end
fixme ("for now, publishing is not implemented, so let's assume any node saved is published.") -- FIXME
- l_node.mark_published
-
+ if l_op_publish then
+ l_node.mark_published
+ elseif l_op_unpublish then
+ l_node.mark_not_published
+ else
+ -- Default status
+ end
node_api.save_node (l_node)
if attached user as u then
api.log ("node",
@@ -362,6 +377,7 @@ feature -- Form
f: CMS_FORM
ts: WSF_FORM_SUBMIT_INPUT
th: WSF_FORM_HIDDEN_INPUT
+ div: WSF_WIDGET_DIV
do
create f.make (a_url, a_name)
create th.make ("node-id")
@@ -375,18 +391,50 @@ feature -- Form
populate_form (a_node_type, f, a_node)
f.extend_html_text (" ")
- create ts.make ("op")
- ts.set_default_value ("Save")
- f.extend (ts)
+
+ create div.make
+ div.add_css_class ("css-editing-buttons")
+ f.extend (div)
create ts.make ("op")
- ts.set_default_value ("Preview")
- f.extend (ts)
+ ts.set_default_value (preview_submit_label)
+ ts.set_description ("Preview without saving.")
+ div.extend (ts)
+ if a_node = Void then
+ create ts.make ("op")
+ ts.set_default_value (save_submit_label)
+ div.extend (ts)
+
+ create ts.make ("op")
+ ts.set_default_value (publish_submit_label)
+ ts.set_description ("Save and mark published.")
+ div.extend (ts)
+ else
+ if a_node.is_published then
+ create ts.make ("op")
+ ts.set_default_value (save_submit_label)
+ ts.set_description ("Save and keep published.")
+ div.extend (ts)
+
+ create ts.make ("op")
+ ts.set_default_value (unpublish_submit_label)
+ ts.set_description ("Save and mark unpublished.")
+ div.extend (ts)
+ else
+ create ts.make ("op")
+ ts.set_default_value (save_submit_label)
+ div.extend (ts)
+
+ create ts.make ("op")
+ ts.set_default_value (publish_submit_label)
+ ts.set_description ("Save and mark published.")
+ div.extend (ts)
+ end
+ end
Result := f
end
-
new_delete_form (a_node: detachable CMS_NODE; a_url: READABLE_STRING_8; a_name: STRING; a_node_type: CMS_NODE_TYPE [CMS_NODE]): CMS_FORM
-- Create a web form named `a_name' for node `a_node' (if set), using form action url `a_url', and for type of node `a_node_type'.
require
@@ -487,4 +535,11 @@ feature -- Form
end
end
+feature -- Labels
+
+ save_submit_label: STRING = "Save"
+ publish_submit_label: STRING = "Publish"
+ unpublish_submit_label: STRING = "Unpublish"
+ preview_submit_label: STRING = "Preview"
+
end
diff --git a/modules/node/handler/node_handler.e b/modules/node/handler/node_handler.e
index 19c3c98..f27056f 100644
--- a/modules/node/handler/node_handler.e
+++ b/modules/node/handler/node_handler.e
@@ -84,6 +84,8 @@ feature -- HTTP Methods
l_nid, l_rev: INTEGER_64
edit_response: NODE_FORM_RESPONSE
view_response: NODE_VIEW_RESPONSE
+ l_is_published: BOOLEAN
+ l_is_denied: BOOLEAN
do
if req.percent_encoded_path_info.ends_with ("/edit") then
check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end
@@ -119,19 +121,26 @@ feature -- HTTP Methods
l_rev := p_rev.value.to_integer_64
end
l_node := node_api.node (l_nid)
- if
- l_node /= Void and then
- l_rev > 0 and then
- l_rev < l_node.revision and then
- node_api.has_permission_for_action_on_node ("view revisions", l_node, api.user)
- then
- l_node := node_api.revision_node (l_nid, l_rev)
+ if l_node /= Void then
+ l_is_published := l_node.is_published
+ if
+ l_rev > 0 and then
+ l_rev < l_node.revision
+ then
+ if node_api.has_permission_for_action_on_node ("view revisions", l_node, api.user) then
+ l_node := node_api.revision_node (l_nid, l_rev)
+ else
+ l_is_denied := True
+ end
+ end
end
- if l_node = Void then
+ if l_is_denied then
+ send_access_denied (req, res)
+ elseif l_node = Void then
send_not_found (req, res)
else
if
- l_rev > 0 or else l_node.is_published
+ l_rev > 0 and l_is_published
then
create view_response.make (req, res, api, node_api)
view_response.set_node (l_node)
@@ -148,7 +157,7 @@ feature -- HTTP Methods
view_response.set_revision (l_rev)
view_response.execute
else
- send_access_denied (req, res)
+ send_access_denied_to_unpublished_node (req, res, l_node)
end
end
else
@@ -392,6 +401,17 @@ feature -- Error
l_page.execute
end
+ send_access_denied_to_unpublished_node (req: WSF_REQUEST; res: WSF_RESPONSE; a_node: CMS_NODE)
+ -- Forbidden response.
+ local
+ r: CMS_RESPONSE
+ do
+ create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
+ r.set_main_content ("This content is NOT published!")
+ r.execute
+ end
+
+
feature {NONE} -- Node
create_new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
diff --git a/src/service/cms_api.e b/src/service/cms_api.e
index 3442596..ea5aca5 100644
--- a/src/service/cms_api.e
+++ b/src/service/cms_api.e
@@ -248,11 +248,8 @@ feature {CMS_API_ACCESS} -- CMS Formats management
-- 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"}, ...}