From c871eae10e535cb38c1b535d84d7ae6b86eae63b Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 27 May 2015 19:00:32 +0200 Subject: [PATCH] Renamed node_api and node_storage by blog_api and blog_storage in related CMS_BLOG_* classes. Mainly to avoid confusion with NODE_ classes. Merged CMS_BLOG_CONFIG with CMS_BLOG_API. In CMS_BLOG_API, prefer argument of type CMS_USER, rather than using directly user id. Added a CMS_EDITOR_CONTENT_FORMAT for now, to be the format editable by the WYSIWYG editor. Added CMS_MODULE.is_initialized: BOOLEAN to equip router, and module_api with expected preconditions. Fixed typo, especially in log output. Corrected a few routine names such as add_authors that should not be a function according to its name. Converted various function returning html content, to procedure appending html content to an output string to minimize temporary string object creation. Cosmetic: added spaces to make code easier to read, and indentation. --- examples/demo/modules/blog/cms_blog.e | 16 +- examples/demo/modules/blog/cms_blog_api.e | 99 +++++---- examples/demo/modules/blog/cms_blog_config.e | 21 -- examples/demo/modules/blog/cms_blog_module.e | 47 ++-- .../demo/modules/blog/cms_blog_node_type.e | 3 +- .../demo/modules/blog/handler/blog_handler.e | 201 +++++++++--------- .../modules/blog/handler/blog_user_handler.e | 104 +++++---- .../modules/blog/handler/cms_blog_handler.e | 9 +- .../blog/persistence/cms_blog_storage_i.e | 16 +- .../blog/persistence/cms_blog_storage_null.e | 16 +- .../blog/persistence/cms_blog_storage_sql.e | 30 +-- modules/node/cms_node_api.e | 1 - .../node/content_type/cms_page_node_type.e | 3 +- .../handler/cms_node_type_webform_manager.e | 27 ++- .../format/cms_editor_content_format.e | 31 +++ src/kernel/content/format/cms_formats.e | 9 +- src/kernel/form/cms_editor.e | 2 - src/kernel/form/cms_form_textarea.e | 27 +-- src/service/cms_api.e | 6 +- src/service/cms_module.e | 11 + 20 files changed, 376 insertions(+), 303 deletions(-) delete mode 100644 examples/demo/modules/blog/cms_blog_config.e create mode 100644 src/kernel/content/format/cms_editor_content_format.e diff --git a/examples/demo/modules/blog/cms_blog.e b/examples/demo/modules/blog/cms_blog.e index f697a1f..2d2a6d3 100644 --- a/examples/demo/modules/blog/cms_blog.e +++ b/examples/demo/modules/blog/cms_blog.e @@ -31,7 +31,13 @@ feature -- Conversion do Precursor (a_node) if attached {CMS_BLOG} a_node as l_blog then --- l_blog + if attached l_blog.tags as l_tags then + across + l_tags as ic + loop + add_tag (ic.item) + end + end end end @@ -42,7 +48,7 @@ feature -- Access Result := {CMS_BLOG_NODE_TYPE}.name end -feature -- Access: content +feature -- Access: node summary: detachable READABLE_STRING_8 -- A short summary of the node. @@ -54,10 +60,12 @@ feature -- Access: content -- Format associated with `content' and `summary'. -- For example: text, mediawiki, html, etc +feature -- Access: blog + tags: detachable ARRAYED_LIST [READABLE_STRING_32] -- Optional tags -feature -- Element change +feature -- Element change: node set_content (a_content: like content; a_summary: like summary; a_format: like format) do @@ -66,6 +74,8 @@ feature -- Element change format := a_format end +feature -- Element change: blog + add_tag (a_tag: READABLE_STRING_32) -- Set `parent' to `a_page' require diff --git a/examples/demo/modules/blog/cms_blog_api.e b/examples/demo/modules/blog/cms_blog_api.e index e75593c..c9128a9 100644 --- a/examples/demo/modules/blog/cms_blog_api.e +++ b/examples/demo/modules/blog/cms_blog_api.e @@ -8,93 +8,108 @@ class CMS_BLOG_API inherit - CMS_NODE_API + CMS_MODULE_API + rename + make as make_with_cms_api redefine - initialize, - node_storage + initialize end + REFACTORING_HELPER + create make -feature {NONE} -- Implementation +feature {NONE} -- Initialization + + make (a_api: CMS_API; a_node_api: CMS_NODE_API) + -- (from CMS_MODULE_API) + -- (export status {NONE}) + do + node_api := a_node_api + make_with_cms_api (a_api) + end initialize -- do Precursor - -- Create the node storage for type blog + + -- Create the node storage for type blog if attached {CMS_STORAGE_SQL_I} storage as l_storage_sql then - create {CMS_BLOG_STORAGE_SQL} node_storage.make (l_storage_sql) + create {CMS_BLOG_STORAGE_SQL} blog_storage.make (l_storage_sql) else - create {CMS_BLOG_STORAGE_NULL} node_storage.make + create {CMS_BLOG_STORAGE_NULL} blog_storage.make end - initialize_node_types +-- initialize_node_types end +feature {CMS_API_ACCESS, CMS_MODULE, CMS_API} -- Restricted access + + node_api: CMS_NODE_API + feature {CMS_MODULE} -- Access nodes storage. - node_storage: CMS_BLOG_STORAGE_I + blog_storage: CMS_BLOG_STORAGE_I + +feature -- Configuration of blog handlers + + entries_per_page : NATURAL_32 = 2 + -- The numbers of posts that are shown on one page. If there are more post a pagination is generated + --| For test reasons this is 2, so we don't have to create a lot of blog entries. + --| TODO: Set to bigger constant. feature -- Access node blogs_count: INTEGER_64 - -- Number of nodes of type blog + -- Number of nodes of type blog. do - Result := node_storage.blogs_count + Result := blog_storage.blogs_count end - blogs_count_from_user (user_id: INTEGER_64) : INTEGER_64 - -- Number of nodes of type blog from user with user_id + blogs_count_from_user (a_user: CMS_USER): INTEGER_64 + -- Number of nodes of type blog from user with `a_user_id'. + require + has_id: a_user.has_id do - Result := node_storage.blogs_count_from_user(user_id) + Result := blog_storage.blogs_count_from_user (a_user) end - blogs_order_created_desc: LIST[CMS_NODE] + blogs_order_created_desc: LIST [CMS_BLOG] -- List of nodes ordered by creation date (descending) do - Result := add_authors(node_storage.blogs) + Result := nodes_to_blogs (blog_storage.blogs) end - blogs_order_created_desc_limited (a_limit:NATURAL_32; a_offset:NATURAL_32) : LIST[CMS_NODE] + blogs_order_created_desc_limited (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_BLOG] -- List of nodes ordered by creation date and limited by limit and offset - local - tmp: LIST[CMS_NODE] do - -- load all posts and add the authors to each post - Result := add_authors(node_storage.blogs_limited (a_limit, a_offset)) - + -- load all posts and add the authors to each post + Result := nodes_to_blogs (blog_storage.blogs_limited (a_limit, a_offset)) end - blogs_from_user_order_created_desc_limited (a_user_id: INTEGER_32; a_limit:NATURAL_32; a_offset:NATURAL_32) : LIST[CMS_NODE] + blogs_from_user_order_created_desc_limited (a_user: CMS_USER; a_limit: NATURAL_32; a_offset: NATURAL_32) : LIST [CMS_BLOG] -- List of nodes ordered by creation date and limited by limit and offset - local - tmp: LIST[CMS_NODE] + require + has_id: a_user.has_id do - -- load all posts and add the authors to each post - Result := add_authors(node_storage.blogs_from_user_limited (a_user_id, a_limit, a_offset)) - + -- load all posts and add the authors to each post + Result := nodes_to_blogs (blog_storage.blogs_from_user_limited (a_user, a_limit, a_offset)) end feature {NONE} -- Helpers - add_authors(posts: LIST[CMS_NODE]) : LIST[CMS_NODE] - -- sets the authors of all given sql results + nodes_to_blogs (a_nodes: LIST [CMS_NODE]): ARRAYED_LIST [CMS_BLOG] + -- Convert list of nodes into a list of blog when possible. do - Result := posts - if posts /= Void then + create {ARRAYED_LIST [CMS_BLOG]} Result.make (a_nodes.count) + + if attached node_api as l_node_api then across - Result - as - sql_result + a_nodes as ic loop - if - sql_result.item /= Void and then - attached {CMS_PARTIAL_USER} sql_result.item.author as l_partial_author - then - if attached cms_api.user_api.user_by_id (l_partial_author.id) as l_author then - sql_result.item.set_author (l_author) - end + if attached {CMS_BLOG} l_node_api.full_node (ic.item) as l_blog then + Result.force (l_blog) end end end diff --git a/examples/demo/modules/blog/cms_blog_config.e b/examples/demo/modules/blog/cms_blog_config.e deleted file mode 100644 index 6be55d8..0000000 --- a/examples/demo/modules/blog/cms_blog_config.e +++ /dev/null @@ -1,21 +0,0 @@ -note - description: "Configuration class for the blog module." - author: "Dario Bösch + node_api: detachable CMS_NODE_API + feature -- Access: router setup_router (a_router: WSF_ROUTER; a_api: CMS_API) -- - local - l_node_api: like node_api do - l_node_api := node_api - if l_node_api = Void then - create l_node_api.make (a_api) - node_api := l_node_api + if attached blog_api as l_blog_api then + configure_web (a_api, l_blog_api, a_router) + else + -- Issue with api/dependencies, + -- thus Current module should not be used! + -- thus no url mapping end - configure_web (a_api, l_node_api, a_router) end - -configure_web (a_api: CMS_API; a_node_api: CMS_BLOG_API; a_router: WSF_ROUTER) + configure_web (a_api: CMS_API; a_blog_api: CMS_BLOG_API; a_router: WSF_ROUTER) + -- Configure router mapping for web interface. local l_blog_handler: BLOG_HANDLER l_blog_user_handler: BLOG_USER_HANDLER l_uri_mapping: WSF_URI_MAPPING do - -- TODO: for now, focused only on web interface, add REST api later. [2015-May-18] - create l_blog_handler.make (a_api, a_node_api) - create l_blog_user_handler.make (a_api, a_node_api) + -- TODO: for now, focused only on web interface, add REST api later. [2015-May-18] + create l_blog_handler.make (a_api, a_blog_api) + create l_blog_user_handler.make (a_api, a_blog_api) - -- Let the class BLOG_HANDLER handle the requests on "/blogs" - create l_uri_mapping.make_trailing_slash_ignored("/blogs", l_blog_handler) + -- Let the class BLOG_HANDLER handle the requests on "/blogs" + create l_uri_mapping.make_trailing_slash_ignored ("/blogs", l_blog_handler) a_router.map_with_request_methods (l_uri_mapping, a_router.methods_get) - -- We can add a page number after /blogs/ to get older posts + -- We can add a page number after /blogs/ to get older posts a_router.handle_with_request_methods ("/blogs/page/{page}", l_blog_handler, a_router.methods_get) - -- If a user id is given route with blog user handler + -- If a user id is given route with blog user handler + --| FIXME: maybe /user/{user}/blogs/ would be better. a_router.handle_with_request_methods ("/blogs/user/{user}", l_blog_user_handler, a_router.methods_get) - -- If a user id is given we also want to allow different pages + -- If a user id is given we also want to allow different pages + --| FIXME: what about /user/{user}/blogs/?page={page} ? a_router.handle_with_request_methods ("/blogs/user/{user}/page/{page}", l_blog_user_handler, a_router.methods_get) end diff --git a/examples/demo/modules/blog/cms_blog_node_type.e b/examples/demo/modules/blog/cms_blog_node_type.e index a393c41..92fd7f5 100644 --- a/examples/demo/modules/blog/cms_blog_node_type.e +++ b/examples/demo/modules/blog/cms_blog_node_type.e @@ -17,10 +17,11 @@ feature {NONE} -- Initialization default_create do Precursor - create {ARRAYED_LIST [like available_formats.item]} available_formats.make (3) + create {ARRAYED_LIST [like available_formats.item]} available_formats.make (4) available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT}) available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT}) available_formats.extend (create {FULL_HTML_CONTENT_FORMAT}) + available_formats.extend (create {CMS_EDITOR_CONTENT_FORMAT}) end feature -- Access diff --git a/examples/demo/modules/blog/handler/blog_handler.e b/examples/demo/modules/blog/handler/blog_handler.e index 536681c..de30e17 100644 --- a/examples/demo/modules/blog/handler/blog_handler.e +++ b/examples/demo/modules/blog/handler/blog_handler.e @@ -8,8 +8,6 @@ class BLOG_HANDLER inherit - CMS_BLOG_CONFIG - CMS_BLOG_HANDLER WSF_URI_HANDLER @@ -41,60 +39,63 @@ create feature -- execute execute (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler + -- Execute request handler for any kind of mapping. do execute_methods (req, res) end uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler + -- Execute request handler for URI mapping. do execute (req, res) end uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler + -- Execute request handler for URI-template mapping. do execute (req, res) end feature -- Global Variables + page_number: NATURAL_32 + -- Current page number. feature -- HTTP Methods + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- local l_page: CMS_RESPONSE do - - -- Read the page number from get variable + -- Read page number from path parameter. page_number := page_number_path_parameter (req) - -- execute response by setting the main content + -- Responding with `main_content_html (l_page)'. create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) - l_page.set_main_content (main_content_html(l_page)) + l_page.set_main_content (main_content_html (l_page)) l_page.execute end feature -- Query - - posts : LIST[CMS_NODE] - -- The posts to list on the given page ordered by date (descending) + posts: LIST [CMS_NODE] + -- Blog posts to display on given page ordered by date (descending). do - Result := node_api.blogs_order_created_desc_limited (entries_per_page, (page_number-1) * entries_per_page) + Result := blog_api.blogs_order_created_desc_limited ( + entries_per_page, + entries_per_page * (page_number - 1) + ) end - more_than_one_page : BOOLEAN - -- Checks if all posts fit on one page (FALSE) or if more than one page is needed (TRUE) + multiple_pages_needed : BOOLEAN + -- Return if more that one page is needed to display posts. do Result := entries_per_page < total_entries end - - pages : NATURAL_32 - -- Returns the number of pages needed to display all posts + pages_count: NATURAL_32 + -- Number of pages needed to display all posts. require entries_per_page > 0 local @@ -105,7 +106,8 @@ feature -- Query end page_number_path_parameter (req: WSF_REQUEST): NATURAL_32 - -- Returns the page number from the path /blogs/{page}. It's an unsigned integer since negative pages are not allowed + -- Page number from path /blogs/{page}. + -- Unsigned integer since negative pages are not allowed. local s: STRING do @@ -120,153 +122,150 @@ feature -- Query end end - total_entries : NATURAL_32 - -- Returns the number of total entries/posts + total_entries: NATURAL_32 + -- Total number of entries/posts. do - Result := node_api.blogs_count.to_natural_32 + Result := blog_api.blogs_count.to_natural_32 end feature -- HTML Output - main_content_html (page: CMS_RESPONSE) : STRING - -- Return the content of the page as a html string + frozen main_content_html (page: CMS_RESPONSE): STRING + -- Content of the page as a html string. + do + create Result.make_empty + append_main_content_html_to (page, Result) + end + + append_main_content_html_to (page: CMS_RESPONSE; a_output: STRING) + -- Append to `a_output, the content of the page as a html string. local n: CMS_NODE lnk: CMS_LOCAL_LINK do - -- Output the title. If more than one page, also output the current page number - create Result.make_from_string (page_title_html) + -- Output the title. If more than one page, also output the current page number + append_page_title_html_to (a_output) - -- Get the posts from the current page (given by page number and entries per page) - if attached posts as lst then + -- Get the posts from the current page (given by page number and entries per page) + -- Start list of posts + a_output.append ("
    %N") + across + posts as ic + loop + n := ic.item + lnk := blog_api.node_api.node_link (n) + a_output.append ("
  • ") - -- Start list of posts - Result.append ("
      %N") - across - lst as ic - loop - n := ic.item - lnk := node_api.node_link (n) - Result.append ("
    • ") + -- Output the creation date + append_creation_date_html_to (n, a_output) - -- Output the creation date - Result.append (creation_date_html(n)) + -- Output the author of the post + append_author_html_to (n, a_output) - -- Output the author of the post - Result.append (author_html(n)) + -- 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) - Result.append (title_html(n, page)) + -- 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 - Result.append (summary_html(n, page)) - - Result.append ("
    • %N") - end - - -- End of post list - Result.append ("
    %N") - - -- Pagination (older and newer links) - Result.append (pagination_html) - - --end + a_output.append ("
  • %N") end + + -- End of post list + a_output.append ("
%N") + + -- Pagination (older and newer links) + append_pagination_html_to (a_output) end - page_title_html : STRING - -- Returns the title of the page as a html string. It shows the current page number + append_page_title_html_to (a_output: STRING) + -- Append the title of the page as a html string to `a_output'. + -- It shows the current page number. do - create Result.make_from_string ("

Blog") - if more_than_one_page then - Result.append (" (Page " + page_number.out + " of " + pages.out + ")") + a_output.append ("

Blog") + if multiple_pages_needed then + a_output.append (" (Page " + page_number.out + " of " + pages_count.out + ")") end - Result.append ("

") + a_output.append ("") end - creation_date_html (n: CMS_NODE) : STRING - -- returns the creation date as a html string + append_creation_date_html_to (n: CMS_NODE; a_output: STRING) + -- Append the creation date as a html string to `a_output'. local hdate: HTTP_DATE do - Result := "" if attached n.creation_date as l_modified then create hdate.make_from_date_time (l_modified) - Result.append (hdate.yyyy_mmm_dd_string) - Result.append (" ") + hdate.append_to_yyyy_mmm_dd_string (a_output) + a_output.append (" ") end end - author_html (n: CMS_NODE) : STRING - -- returns a html string with a link to the autors posts + append_author_html_to (n: CMS_NODE; a_output: STRING) + -- Append to `a_output', the author of node `n' as html link to author's posts. do - Result := "" if attached n.author as l_author then - Result.append ("by ") - Result.append ("" + l_author.name + "") + a_output.append ("by ") + a_output.append ("" + l_author.name + "") end end - title_html (n: CMS_NODE; page : CMS_RESPONSE) : STRING - -- returns a html string the title of the node that links on the detail page + append_title_html_to (n: CMS_NODE; page: CMS_RESPONSE; a_output: STRING) + -- Append to `a_output', the title of node `n' as html link to detail page. local lnk: CMS_LOCAL_LINK do - lnk := node_api.node_link (n) - Result := "" - Result.append (page.link (lnk.title, lnk.location, Void)) - Result.append ("") + lnk := blog_api.node_api.node_link (n) + a_output.append ("") + a_output.append (page.link (lnk.title, lnk.location, Void)) + a_output.append ("") end - summary_html (n: CMS_NODE; page : CMS_RESPONSE) : STRING + append_summary_html_to (n: CMS_NODE; page: CMS_RESPONSE; a_output: STRING) -- returns a html string with the summary of the node and a link to the detail page local lnk: CMS_LOCAL_LINK do - Result := "" - lnk := node_api.node_link (n) if attached n.summary as l_summary then - Result.append ("

") + lnk := blog_api.node_api.node_link (n) + a_output.append ("

") if attached api.format (n.format) as f then - Result.append (f.formatted_output (l_summary)) + a_output.append (f.formatted_output (l_summary)) else - Result.append (page.formats.default_format.formatted_output (l_summary)) + a_output.append (page.formats.default_format.formatted_output (l_summary)) end - Result.append ("
") - Result.append (page.link ("See more...", lnk.location, Void)) - Result.append ("

") + a_output.append ("
") + a_output.append (page.link ("See more...", lnk.location, Void)) + a_output.append ("

") end end - pagination_html : STRING - -- returns a html string with the pagination links (if necessary) + append_pagination_html_to (a_output: STRING) + -- Append to `a_output' with the pagination links (if necessary). local tmp: NATURAL_32 do - Result := "" - if more_than_one_page then + if multiple_pages_needed then + a_output.append ("
") - Result.append ("
") - - -- If exist older posts show link to next page - if page_number < pages then + -- If exist older posts show link to next page + if page_number < pages_count then tmp := page_number + 1 - Result.append (" << Older Posts ") + a_output.append (" << Older Posts ") end - -- Delmiter - if page_number < pages AND page_number > 1 then - Result.append (" | ") + -- Delimiter + if page_number < pages_count AND page_number > 1 then + a_output.append (" | ") end -- If exist newer posts show link to previous page if page_number > 1 then tmp := page_number -1 - Result.append (" Newer Posts >> ") + a_output.append (" Newer Posts >> ") end - Result.append ("
") - + a_output.append ("
") end end diff --git a/examples/demo/modules/blog/handler/blog_user_handler.e b/examples/demo/modules/blog/handler/blog_user_handler.e index 58fff51..961fe35 100644 --- a/examples/demo/modules/blog/handler/blog_user_handler.e +++ b/examples/demo/modules/blog/handler/blog_user_handler.e @@ -1,5 +1,11 @@ note - description: "Request handler related to /blogs/user/{id}/ or /blogs/user/{id}/page/{page}. Displays all posts of the given user" + description: "[ + Request handler related to + /blogs/user/{id}/ + or /blogs/user/{id}/page/{page}. + + Displays all posts of the given user + ]" author: "Dario Bösch " date: "$Date: 2015-05-22 15:13:00 +0100 (lun., 18 mai 2015) $" revision: "$Revision 96616$" @@ -13,14 +19,13 @@ inherit do_get, posts, total_entries, - page_title_html, + append_page_title_html_to, base_path end create make - feature -- Global Variables user : detachable CMS_USER @@ -30,71 +35,76 @@ feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- local - l_error: GENERIC_VIEW_CMS_RESPONSE + l_error: NOT_FOUND_ERROR_CMS_RESPONSE do - -- Check if userID valid - if user_valid (req) then - user := load_user(req) - -- Output the results, similar as in the blog hanlder (but with other queries) - precursor(req, res) + user := Void + if attached user_from_request (req) as l_user then + user := l_user + -- Output the results, similar as in the blog hanlder (but with other queries) + Precursor (req, res) else - -- Throw a bad request error because the user is not valid + -- Throw a bad request error because the user is not valid create l_error.make (req, res, api) - l_error.set_main_content ("

Error

User with id " + user_path_parameter(req).out + " doesn't exist!") + l_error.set_main_content ("

Error

User with id " + user_id_path_parameter (req).out + " doesn't exist!") l_error.execute end - end feature -- Query user_valid (req: WSF_REQUEST) : BOOLEAN - -- Returns true if a valid user id is given and a user with this id exists; otherwise returns false. + -- Returns true if a valid user id is given and a user with this id exists, + -- otherwise returns false. local user_id: INTEGER_32 do - - user_id := user_path_parameter(req) + user_id := user_id_path_parameter (req) if user_id <= 0 then - --Given user id is not valid - Result := false + -- Given user id is not valid + Result := False else - --Check if user with user_id exists + --Check if user with user_id exists Result := api.user_api.user_by_id (user_id) /= Void end end - load_user (req: WSF_REQUEST) : detachable CMS_USER - -- Returnes the user with the given id in the request req - require - user_valid(req) + user_from_request (req: WSF_REQUEST): detachable CMS_USER + -- Eventual user with given id in the path of request `req'. + local + uid: like user_id_path_parameter do - Result := api.user_api.user_by_id (user_path_parameter(req)) + uid := user_id_path_parameter (req) + if uid > 0 then + Result := api.user_api.user_by_id (uid) + else + -- Missing or invalid user id. + end end - user_path_parameter (req: WSF_REQUEST): INTEGER_32 - -- Returns the user id from the path /blogs/{user}. It's an unsigned integer since negative ids are not allowed. If no valid id can be read it returns -1 + user_id_path_parameter (req: WSF_REQUEST): INTEGER_32 + -- User id from path /blogs/{user}. + -- Unsigned integer since negative ids are not allowed. + -- If no valid id can be read it returns -1 local s: STRING do - if attached {WSF_STRING} req.path_parameter ("user") as user_id then - s := user_id.value - if s.is_integer_32 then - if s.to_integer_32 > 0 then - Result := s.to_integer_32 - end + Result := -1 + if attached {WSF_STRING} req.path_parameter ("user") as l_user_id then + if l_user_id.is_integer then + Result := l_user_id.integer_value end end end - posts : LIST[CMS_NODE] - -- The posts to list on the given page. Filters out the posts of the current user + posts: LIST [CMS_BLOG] + -- Blog posts to display on given page. + -- Filters out the posts of the current user. do if attached user as l_user then - Result := node_api.blogs_from_user_order_created_desc_limited (l_user.id.to_integer_32, entries_per_page, (page_number-1) * entries_per_page) + Result := blog_api.blogs_from_user_order_created_desc_limited (l_user, entries_per_page, entries_per_page * (page_number - 1)) else - create {ARRAYED_LIST [CMS_NODE]} Result.make (0) + create {ARRAYED_LIST [CMS_BLOG]} Result.make (0) end end @@ -102,33 +112,33 @@ feature -- Query -- Returns the number of total entries/posts of the current user do if attached user as l_user then - Result := node_api.blogs_count_from_user(l_user.id).to_natural_32 + Result := blog_api.blogs_count_from_user (l_user).to_natural_32 else - Result := precursor + Result := Precursor end - end feature -- HTML Output - page_title_html : STRING + append_page_title_html_to (a_output: STRING) -- Returns the title of the page as a html string. It shows the current page number and the name of the current user do - create Result.make_from_string ("

Posts from ") + a_output.append ("

Posts from ") if attached user as l_user then - Result.append(l_user.name) + a_output.append (l_user.name) else - Result.append ("unknown user") + a_output.append ("unknown user") end - if more_than_one_page then - Result.append (" (Page " + page_number.out + " of " + pages.out + ")") - -- Get the posts from the current page (limited by entries per page) + if multiple_pages_needed then + a_output.append (" (Page " + page_number.out + " of " + pages_count.out + ")") + -- Get the posts from the current page (limited by entries per page) end - Result.append ("

") + a_output.append ("") end base_path : STRING - -- the path to the page that lists all blogs. It must include the user id + -- Path to page listing all blogs. + -- If user is logged in, include user id do if attached user as l_user then Result := "/blogs/user/" + l_user.id.out diff --git a/examples/demo/modules/blog/handler/cms_blog_handler.e b/examples/demo/modules/blog/handler/cms_blog_handler.e index bef34e5..450096f 100644 --- a/examples/demo/modules/blog/handler/cms_blog_handler.e +++ b/examples/demo/modules/blog/handler/cms_blog_handler.e @@ -10,7 +10,14 @@ deferred class inherit CMS_MODULE_HANDLER [CMS_BLOG_API] rename - module_api as node_api + module_api as blog_api + end + +feature -- Access + + entries_per_page: NATURAL_32 + do + Result := blog_api.entries_per_page end end diff --git a/examples/demo/modules/blog/persistence/cms_blog_storage_i.e b/examples/demo/modules/blog/persistence/cms_blog_storage_i.e index 8fd8ca7..08c2447 100644 --- a/examples/demo/modules/blog/persistence/cms_blog_storage_i.e +++ b/examples/demo/modules/blog/persistence/cms_blog_storage_i.e @@ -16,8 +16,10 @@ feature -- Access deferred end - blogs_count_from_user (user_id: INTEGER_64) : INTEGER_64 - -- Number of nodes of type blog from user with user_id + blogs_count_from_user (a_user: CMS_USER) : INTEGER_64 + -- Number of nodes of type blog from `a_user'. + require + has_id: a_user.has_id deferred end @@ -26,13 +28,15 @@ feature -- Access deferred end - blogs_limited (limit:NATURAL_32; offset:NATURAL_32) : LIST[CMS_NODE] - -- List of posts ordered by creation date from offset to offset + limit + blogs_limited (limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE] + -- List of posts ordered by creation date from offset to offset + limit. deferred end - blogs_from_user_limited (user_id: INTEGER_32; limit:NATURAL_32; offset:NATURAL_32) : LIST[CMS_NODE] - -- List of posts from user_id ordered by creation date from offset to offset + limit + blogs_from_user_limited (a_user: CMS_USER; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE] + -- List of posts from `a_user' ordered by creation date from offset to offset + limit. + require + has_id: a_user.has_id deferred end diff --git a/examples/demo/modules/blog/persistence/cms_blog_storage_null.e b/examples/demo/modules/blog/persistence/cms_blog_storage_null.e index d208190..40a860f 100644 --- a/examples/demo/modules/blog/persistence/cms_blog_storage_null.e +++ b/examples/demo/modules/blog/persistence/cms_blog_storage_null.e @@ -22,25 +22,25 @@ feature -- Access do end - blogs_count_from_user (user_id: INTEGER_64) : INTEGER_64 - -- Number of nodes of type blog from user with user_id + blogs_count_from_user (a_user: CMS_USER) : INTEGER_64 + -- do end - blogs: LIST[CMS_NODE] - -- List of nodes. + blogs: LIST [CMS_NODE] + -- do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) end - blogs_limited (limit:NATURAL_32; offset:NATURAL_32) : LIST[CMS_NODE] - -- List of posts ordered by creation date from offset to offset + limit + blogs_limited (limit: NATURAL_32; offset: NATURAL_32) : LIST [CMS_NODE] + -- do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) end - blogs_from_user_limited (user_id: INTEGER_32; limit:NATURAL_32; offset:NATURAL_32) : LIST[CMS_NODE] - -- List of posts from user_id ordered by creation date from offset to offset + limit + blogs_from_user_limited (a_user: CMS_USER; limit: NATURAL_32; offset: NATURAL_32): LIST [CMS_NODE] + -- do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) end diff --git a/examples/demo/modules/blog/persistence/cms_blog_storage_sql.e b/examples/demo/modules/blog/persistence/cms_blog_storage_sql.e index 915ad20..ad07f62 100644 --- a/examples/demo/modules/blog/persistence/cms_blog_storage_sql.e +++ b/examples/demo/modules/blog/persistence/cms_blog_storage_sql.e @@ -18,25 +18,25 @@ create feature -- Access blogs_count: INTEGER_64 - -- Count of blog nodes + -- do error_handler.reset - write_information_log (generator + ".nodes_count") + write_information_log (generator + ".blogs_count") sql_query (sql_select_blog_count, Void) if sql_rows_count = 1 then Result := sql_read_integer_64 (1) end end - blogs_count_from_user (user_id: INTEGER_64) : INTEGER_64 - -- Number of nodes of type blog from user with user_id + blogs_count_from_user (a_user: CMS_USER) : INTEGER_64 + -- local l_parameters: STRING_TABLE [detachable ANY] do error_handler.reset - write_information_log (generator + ".nodes_count") + write_information_log (generator + ".blogs_count_from_user") create l_parameters.make (2) - l_parameters.put (user_id, "user") + l_parameters.put (a_user.id, "user") sql_query (sql_select_blog_count_from_user, l_parameters) if sql_rows_count = 1 then Result := sql_read_integer_64 (1) @@ -44,12 +44,12 @@ feature -- Access end blogs: LIST [CMS_NODE] - -- List of nodes ordered by creation date (descending). + -- do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) error_handler.reset - write_information_log (generator + ".nodes") + write_information_log (generator + ".blogs") from sql_query (sql_select_blogs_order_created_desc, Void) @@ -64,15 +64,15 @@ feature -- Access end end - blogs_limited (a_limit:NATURAL_32; a_offset:NATURAL_32) : LIST[CMS_NODE] - -- List of nodes ordered by creation date from limit to limit + offset + blogs_limited (a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE] + -- local l_parameters: STRING_TABLE [detachable ANY] do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) error_handler.reset - write_information_log (generator + ".nodes") + write_information_log (generator + ".blogs_limited") from create l_parameters.make (2) @@ -90,21 +90,21 @@ feature -- Access end end - blogs_from_user_limited (a_user_id:INTEGER_32; a_limit:NATURAL_32; a_offset:NATURAL_32) : LIST[CMS_NODE] - -- List of posts of the author with a_user_id ordered by creation date starting at offset and limited by limit + blogs_from_user_limited (a_user: CMS_USER; a_limit: NATURAL_32; a_offset: NATURAL_32): LIST [CMS_NODE] + -- local l_parameters: STRING_TABLE [detachable ANY] do create {ARRAYED_LIST [CMS_NODE]} Result.make (0) error_handler.reset - write_information_log (generator + ".nodes") + write_information_log (generator + ".blogs_from_user_limited") from create l_parameters.make (2) l_parameters.put (a_limit, "limit") l_parameters.put (a_offset, "offset") - l_parameters.put (a_user_id, "user") + l_parameters.put (a_user.id, "user") sql_query (sql_blogs_from_user_limited, l_parameters) sql_start until diff --git a/modules/node/cms_node_api.e b/modules/node/cms_node_api.e index d324d3b..8f0a8d9 100644 --- a/modules/node/cms_node_api.e +++ b/modules/node/cms_node_api.e @@ -212,7 +212,6 @@ feature -- Access: Node Result := node_storage.nodes end - recent_nodes (a_offset, a_rows: INTEGER): LIST [CMS_NODE] -- List of the `a_rows' most recent nodes starting from `a_offset'. do diff --git a/modules/node/content_type/cms_page_node_type.e b/modules/node/content_type/cms_page_node_type.e index 2053e0d..3fe15b3 100644 --- a/modules/node/content_type/cms_page_node_type.e +++ b/modules/node/content_type/cms_page_node_type.e @@ -17,10 +17,11 @@ feature {NONE} -- Initialization default_create do Precursor - create {ARRAYED_LIST [like available_formats.item]} available_formats.make (3) + create {ARRAYED_LIST [like available_formats.item]} available_formats.make (4) available_formats.extend (create {PLAIN_TEXT_CONTENT_FORMAT}) available_formats.extend (create {FILTERED_HTML_CONTENT_FORMAT}) available_formats.extend (create {FULL_HTML_CONTENT_FORMAT}) + available_formats.extend (create {CMS_EDITOR_CONTENT_FORMAT}) end feature -- Access diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index 984f0d5..3ff29a8 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -18,8 +18,10 @@ feature -- Forms ... ta, sum: CMS_FORM_TEXTAREA tselect: WSF_FORM_SELECT opt: WSF_FORM_SELECT_OPTION - full_format: FULL_HTML_CONTENT_FORMAT + cms_format: CMS_EDITOR_CONTENT_FORMAT do + create cms_format + create ti.make ("title") ti.set_label ("Title") ti.set_size (70) @@ -31,18 +33,16 @@ feature -- Forms ... f.extend_html_text ("
") - -- Select field has to be initialized before textareas are replaced, because they depend on the selection of the field + -- Select field has to be initialized before textareas are replaced, because they depend on the selection of the field create tselect.make ("format") tselect.set_label ("Body's format") tselect.set_is_required (True) - - create full_format.default_create - -- Main Content + -- Main Content create ta.make ("body") ta.set_rows (10) ta.set_cols (70) - ta.show_as_editor_if_selected (tselect, full_format.name) + ta.show_as_editor_if_selected (tselect, cms_format.name) if a_node /= Void then ta.set_text_value (a_node.content) end @@ -50,12 +50,12 @@ feature -- Forms ... ta.set_description ("This is the main content") ta.set_is_required (False) - -- Summary + -- Summary create sum.make ("summary") - sum.set_rows (10) + sum.set_rows (3) sum.set_cols (70) - -- if full_html is selected - sum.show_as_editor_if_selected (tselect, full_format.name) + -- if cms_html is selected + sum.show_as_editor_if_selected (tselect, cms_format.name) if a_node /= Void then sum.set_text_value (a_node.summary) end @@ -66,15 +66,14 @@ feature -- Forms ... create fset.make fset.set_legend ("Body") - -- Add summary + -- Add summary fset.extend (sum) fset.extend_html_text("
") - -- Add content (body) + -- Add content (body) fset.extend (ta) fset.extend_html_text ("
") - across content_type.available_formats as c loop @@ -92,7 +91,7 @@ feature -- Forms ... f.extend (fset) - -- Path aliase + -- Path alias create ti.make ("path_alias") ti.set_label ("Path") ti.set_size (70) diff --git a/src/kernel/content/format/cms_editor_content_format.e b/src/kernel/content/format/cms_editor_content_format.e new file mode 100644 index 0000000..69e256e --- /dev/null +++ b/src/kernel/content/format/cms_editor_content_format.e @@ -0,0 +1,31 @@ +note + description: "HTML Content format editable with WYSIWYG editor." + date: "$Date$" + revision: "$Revision$" + +class + CMS_EDITOR_CONTENT_FORMAT + +inherit + CONTENT_FORMAT + redefine + default_create + end + +feature {NONE} -- Initialization + + default_create + do + Precursor + create filters.make (0) + end + +feature -- Access + + name: STRING = "cms_editor" + + title: STRING_8 = "CMS HTML content" + + filters: ARRAYED_LIST [CONTENT_FILTER] + +end diff --git a/src/kernel/content/format/cms_formats.e b/src/kernel/content/format/cms_formats.e index 12132d0..199062d 100644 --- a/src/kernel/content/format/cms_formats.e +++ b/src/kernel/content/format/cms_formats.e @@ -27,10 +27,11 @@ feature -- Access once -- Can we provide an external file to read the -- supported formats? - create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (3) + create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (4) Result.force (plain_text) Result.force (full_html) Result.force (filtered_html) + Result.force (cms_html) end default_format: CONTENT_FORMAT @@ -43,6 +44,11 @@ feature -- Access create Result end + cms_html: CMS_EDITOR_CONTENT_FORMAT + once + create Result + end + full_html: FULL_HTML_CONTENT_FORMAT once create Result @@ -53,7 +59,6 @@ feature -- Access create Result end - note copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/src/kernel/form/cms_editor.e b/src/kernel/form/cms_editor.e index 910ec42..5913956 100644 --- a/src/kernel/form/cms_editor.e +++ b/src/kernel/form/cms_editor.e @@ -27,8 +27,6 @@ feature -- Javascript javascript_textarea_to_editor(a_textarea : WSF_FORM_TEXTAREA) : STRING -- Javascript code to display the textarea as a WYSIWIG editor as soon as the document is loaded - local - l_code : STRING do Result := javascript_ready(javascript_replace_textarea (a_textarea)) end diff --git a/src/kernel/form/cms_form_textarea.e b/src/kernel/form/cms_form_textarea.e index 4f68343..60df239 100644 --- a/src/kernel/form/cms_form_textarea.e +++ b/src/kernel/form/cms_form_textarea.e @@ -21,22 +21,22 @@ create feature -- Initialisation -make (a_name: like name) - -- - do - precursor(a_name) + make (a_name: like name) + -- + do + precursor(a_name) - -- By default we don't replace the textarea by an editor - editor := False; - end + -- By default we don't replace the textarea by an editor + editor := False; + end feature -- Access editor : BOOLEAN - -- True if the textarea should be replaced by the editor. Default is false. + -- True if the textarea should be replaced by the editor. Default is false. format_field : detachable WSF_FORM_SELECT - -- Selection field for the format on that it depends, if the editor is shown or not. + -- Selection field for the format on that it depends, if the editor is shown or not. condition_value : detachable STRING @@ -58,7 +58,6 @@ feature -- Editor feature -- Conversion - append_item_to_html (a_theme: WSF_THEME; a_html: STRING_8) do -- Add javascript to replace textarea with editor @@ -67,16 +66,12 @@ feature -- Conversion a_html.append (load_assets) a_html.append ("") end end -feature -- Javascript Output - - javascript_show_editor_on_full_html_select : STRING = "" - end diff --git a/src/service/cms_api.e b/src/service/cms_api.e index 19dbebf..c245a43 100644 --- a/src/service/cms_api.e +++ b/src/service/cms_api.e @@ -185,8 +185,10 @@ feature -- Query: module module_api (a_type: TYPE [CMS_MODULE]): detachable CMS_MODULE_API -- Enabled module API associated with module typed `a_type'. do - if attached module (a_type) as mod then - Result := mod.module_api + if attached {CMS_MODULE} module (a_type) as mod then + if mod.is_enabled then + Result := mod.module_api + end end end diff --git a/src/service/cms_module.e b/src/service/cms_module.e index adc48c6..356cb5f 100644 --- a/src/service/cms_module.e +++ b/src/service/cms_module.e @@ -32,10 +32,19 @@ feature {CMS_API} -- Module Initialization -- Initialize Current module with `api'. require is_enabled: is_enabled + is_not_initialized: not is_initialized do -- Redefine to process specific module initialization. + is_initialized := True + ensure + is_initialized: is_initialized end +feature -- Status + + is_initialized: BOOLEAN + -- Is Current module initialized? + feature {CMS_API} -- Access: API module_api: detachable CMS_MODULE_API @@ -68,6 +77,8 @@ feature -- Router setup_router (a_router: WSF_ROUTER; a_api: CMS_API) -- Setup url dispatching for Current module. + require + is_initialized: is_initialized deferred end