From 241b0035428d9cb72cb40ce1d20f3fc6af829e84 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Nov 2014 14:59:17 +0100 Subject: [PATCH 1/4] Renamed CMS_API_SERVICE as CMS_API . Reversed the design, and break dependency CMS_SETUP => CMS_API . Now CMS_API has attribute setup: CMS_SETUP . Moved error_handler from CMS_SETUP to CMS_API. The instance of CMS_SETUP is used when instanciating modules. The instance of CMS_API is used when instanciating CMS_REPONSE and Handlers/Filters. The instance of CMS_API is passed as argument to build the CMS_MODULE.router and filter. --- cms/src/configuration/cms_default_setup.e | 45 ------------- cms/src/configuration/cms_setup.e | 9 --- .../modules/basic_auth/basic_auth_module.e | 25 +++---- .../basic_auth/filter/basic_auth_filter.e | 4 +- .../handler/basic_auth_logoff_handler.e | 2 +- cms/src/modules/cms_module.e | 6 +- .../node/handler/node_content_handler.e | 20 +++--- cms/src/modules/node/handler/node_handler.e | 26 ++++---- .../node/handler/node_summary_handler.e | 20 +++--- .../modules/node/handler/node_title_handler.e | 20 +++--- cms/src/modules/node/handler/nodes_handler.e | 4 +- cms/src/modules/node/node_module.e | 42 ++++++------ .../service/{cms_api_service.e => cms_api.e} | 65 +++++++++++++++++-- cms/src/service/cms_service.e | 42 +++++++----- cms/src/service/filter/cms_error_filter.e | 8 +-- cms/src/service/handler/cms_handler.e | 12 ++-- cms/src/service/handler/cms_root_handler.e | 2 +- cms/src/service/response/cms_response.e | 16 +++-- cms/src/service/response/home_cms_response.e | 2 +- .../roc_api/modules/demo/cms_demo_module.e | 8 +-- examples/roc_api/src/ewf_roc_server.e | 11 ++-- 21 files changed, 195 insertions(+), 194 deletions(-) rename cms/src/service/{cms_api_service.e => cms_api.e} (55%) diff --git a/cms/src/configuration/cms_default_setup.e b/cms/src/configuration/cms_default_setup.e index eabc20c..76dcab2 100644 --- a/cms/src/configuration/cms_default_setup.e +++ b/cms/src/configuration/cms_default_setup.e @@ -17,7 +17,6 @@ feature {NONE} -- Initialization make (a_layout: CMS_LAYOUT) do - create error_handler.make layout := a_layout create configuration.make (layout) initialize @@ -27,7 +26,6 @@ feature {NONE} -- Initialization do configure create modules.make (3) - build_api_service build_mailer initialize_modules end @@ -85,49 +83,6 @@ feature -- Access end - build_api_service - local - l_database: DATABASE_CONNECTION - l_retry: BOOLEAN - l_message: STRING - do - if not l_retry then - to_implement ("Refactor database setup") - if attached (create {JSON_CONFIGURATION}).new_database_configuration (layout.application_config_path) as l_database_config then - create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string) - create api_service.make (create {CMS_STORAGE_MYSQL}.make (l_database)) - else - create {DATABASE_CONNECTION_NULL} l_database.make_common - create api_service.make (create {CMS_STORAGE_NULL}) - end - else - to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.") - -- error hanling. - create {DATABASE_CONNECTION_NULL} l_database.make_common - create api_service.make (create {CMS_STORAGE_NULL}) - create l_message.make (1024) - if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then - if attached l_exception.description as l_description then - l_message.append (l_description.as_string_32) - l_message.append ("%N%N") - elseif attached l_exception.trace as l_trace then - l_message.append (l_trace) - l_message.append ("%N%N") - else - l_message.append (l_exception.out) - l_message.append ("%N%N") - end - else - l_message.append ("The application crash without available information") - l_message.append ("%N%N") - end - error_handler.add_custom_error (0, " Database Connection ", l_message) - end - rescue - l_retry := True - retry - end - build_auth_engine do to_implement ("Not implemented authentication") diff --git a/cms/src/configuration/cms_setup.e b/cms/src/configuration/cms_setup.e index 0e6189d..6659735 100644 --- a/cms/src/configuration/cms_setup.e +++ b/cms/src/configuration/cms_setup.e @@ -14,9 +14,6 @@ feature -- Access layout: CMS_LAYOUT -- CMS layout. - api_service: CMS_API_SERVICE - -- cms api service. - is_html: BOOLEAN -- api with progressive enhancements css and js, server side rendering. deferred @@ -32,12 +29,6 @@ feature -- Access deferred end - -feature -- Status Report - - error_handler: ERROR_HANDLER - -- Error handler. - feature -- Access: Site site_id: READABLE_STRING_8 diff --git a/cms/src/modules/basic_auth/basic_auth_module.e b/cms/src/modules/basic_auth/basic_auth_module.e index 1afac3e..a198ed7 100644 --- a/cms/src/modules/basic_auth/basic_auth_module.e +++ b/cms/src/modules/basic_auth/basic_auth_module.e @@ -18,63 +18,58 @@ create feature {NONE} -- Initialization - make (a_config: CMS_SETUP) + make do name := "basic auth" version := "1.0" description := "Service to manage basic authentication" package := "core" - config := a_config end - config: CMS_SETUP - -- Node configuration. - feature -- Access: router - router: WSF_ROUTER + router (a_api: CMS_API): WSF_ROUTER -- Node router. do create Result.make (2) - configure_api_login (Result) - configure_api_logoff (Result) + configure_api_login (a_api, Result) + configure_api_logoff (a_api, Result) end feature -- Access: filter - filters: detachable LIST [WSF_FILTER] + filters (a_api: CMS_API): detachable LIST [WSF_FILTER] -- Possibly list of Filter's module. do create {ARRAYED_LIST [WSF_FILTER]} Result.make (2) Result.extend (create {CORS_FILTER}) - Result.extend (create {BASIC_AUTH_FILTER}.make (config)) + Result.extend (create {BASIC_AUTH_FILTER}.make (a_api)) end feature {NONE} -- Implementation: routes - configure_api_login (a_router: WSF_ROUTER) + configure_api_login (api: CMS_API; a_router: WSF_ROUTER) local l_bal_handler: BASIC_AUTH_LOGIN_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_bal_handler.make (config) + create l_bal_handler.make (api) create l_methods l_methods.enable_get a_router.handle_with_request_methods ("/basic_auth_login", l_bal_handler, l_methods) end - configure_api_logoff (a_router: WSF_ROUTER) + configure_api_logoff (api: CMS_API; a_router: WSF_ROUTER) local l_bal_handler: BASIC_AUTH_LOGOFF_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_bal_handler.make (config) + create l_bal_handler.make (api) create l_methods l_methods.enable_get a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods) end - feature -- Hooks register_hooks (a_response: CMS_RESPONSE) diff --git a/cms/src/modules/basic_auth/filter/basic_auth_filter.e b/cms/src/modules/basic_auth/filter/basic_auth_filter.e index d5abd0a..31ddb21 100644 --- a/cms/src/modules/basic_auth/filter/basic_auth_filter.e +++ b/cms/src/modules/basic_auth/filter/basic_auth_filter.e @@ -31,8 +31,8 @@ feature -- Basic operations -- A valid user if (attached l_auth.type as l_auth_type and then l_auth_type.is_case_insensitive_equal_general ("basic")) and then attached l_auth.login as l_auth_login and then attached l_auth.password as l_auth_password then - if api_service.is_valid_credential (l_auth_login, l_auth_password) then - if attached api_service.user_by_name (l_auth_login) as l_user then + if api.is_valid_credential (l_auth_login, l_auth_password) then + if attached api.user_by_name (l_auth_login) as l_user then req.set_execution_variable ("user", l_user) execute_next (req, res) else diff --git a/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e b/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e index ecf3e7b..300eafe 100644 --- a/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e +++ b/cms/src/modules/basic_auth/handler/basic_auth_logoff_handler.e @@ -50,7 +50,7 @@ feature -- HTTP Methods if attached req.query_parameter ("prompt") as l_prompt then (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) else - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized) l_page.execute end diff --git a/cms/src/modules/cms_module.e b/cms/src/modules/cms_module.e index f7d1eac..6632eba 100644 --- a/cms/src/modules/cms_module.e +++ b/cms/src/modules/cms_module.e @@ -20,15 +20,13 @@ feature -- Access feature -- Router - router: WSF_ROUTER + router (a_api: CMS_API): WSF_ROUTER -- Router configuration. require is_enabled: is_enabled deferred end - - feature -- Hooks configuration register_hooks (a_response: CMS_RESPONSE) @@ -40,7 +38,7 @@ feature -- Hooks configuration feature -- Filter - filters: detachable LIST [WSF_FILTER] + filters (a_api: CMS_API): detachable LIST [WSF_FILTER] -- Optional list of filter for Current module. require is_enabled: is_enabled diff --git a/cms/src/modules/node/handler/node_content_handler.e b/cms/src/modules/node/handler/node_content_handler.e index 4232053..11ebd9d 100644 --- a/cms/src/modules/node/handler/node_content_handler.e +++ b/cms/src/modules/node/handler/node_content_handler.e @@ -69,8 +69,8 @@ feature -- HTTP Methods if attached current_user_name (req) then -- Existing node if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (l_node.content, "node_content") l_page.add_variable (l_id.value, "id") l_page.execute @@ -78,7 +78,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -91,19 +91,19 @@ feature -- HTTP Methods do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then if attached {WSF_STRING} req.form_parameter ("method") as l_method then if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -118,16 +118,16 @@ feature -- HTTP Methods to_implement ("Check if user has permissions") if attached current_user (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then u_node := extract_data_form (req) u_node.set_id (l_id.integer_value) - api_service.update_node_content (l_user.id, u_node.id, u_node.content) + api.update_node_content (l_user.id, u_node.id, u_node.content) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -140,7 +140,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/node_handler.e b/cms/src/modules/node/handler/node_handler.e index c4e5bf9..2dcb47f 100644 --- a/cms/src/modules/node/handler/node_handler.e +++ b/cms/src/modules/node/handler/node_handler.e @@ -68,8 +68,8 @@ feature -- HTTP Methods do -- Existing node if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (l_node, "node") l_page.execute else @@ -89,14 +89,14 @@ feature -- HTTP Methods to_implement ("Check user permissions!!!") if attached current_user (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then if attached {WSF_STRING} req.form_parameter ("method") as l_method then if l_method.is_case_insensitive_equal ("DELETE") then do_delete (req, res) elseif l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end end else @@ -106,7 +106,7 @@ feature -- HTTP Methods -- New node u_node := extract_data_form (req) u_node.set_author (l_user) - api_service.new_node (u_node) + api.new_node (u_node) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) end else @@ -122,16 +122,16 @@ feature -- HTTP Methods if attached current_user (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then u_node := extract_data_form (req) u_node.set_id (l_id.integer_value) - api_service.update_node (l_user.id,u_node) + api.update_node (l_user.id,u_node) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -144,14 +144,14 @@ feature -- HTTP Methods do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then - api_service.delete_node (l_id.integer_value) + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then + api.delete_node (l_id.integer_value) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -165,7 +165,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found @@ -186,7 +186,7 @@ feature {NONE} -- Node l_page: CMS_RESPONSE do if attached current_user_name (req) then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (setup.is_html, "html") l_page.add_variable (setup.is_web, "web") l_page.execute diff --git a/cms/src/modules/node/handler/node_summary_handler.e b/cms/src/modules/node/handler/node_summary_handler.e index 585a050..01553b2 100644 --- a/cms/src/modules/node/handler/node_summary_handler.e +++ b/cms/src/modules/node/handler/node_summary_handler.e @@ -68,8 +68,8 @@ feature -- HTTP Methods if attached current_user_name (req) then -- Existing node if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (l_id.value, "id") l_page.add_variable (l_node.summary, "node_summary") l_page.execute @@ -77,7 +77,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -90,19 +90,19 @@ feature -- HTTP Methods do if attached current_user_name (req) then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then if attached {WSF_STRING} req.form_parameter ("method") as l_method then if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -116,16 +116,16 @@ feature -- HTTP Methods do if attached current_user (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then u_node := extract_data_form (req) u_node.set_id (l_id.integer_value) - api_service.update_node_summary (l_user.id,u_node.id, u_node.summary) + api.update_node_summary (l_user.id,u_node.id, u_node.summary) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -140,7 +140,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/node_title_handler.e b/cms/src/modules/node/handler/node_title_handler.e index e1baa7b..0cfe30d 100644 --- a/cms/src/modules/node/handler/node_title_handler.e +++ b/cms/src/modules/node/handler/node_title_handler.e @@ -68,8 +68,8 @@ feature -- HTTP Methods if attached current_user_name (req) as l_user then -- Existing node if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (l_node.title, "node_title") l_page.add_variable (l_id.value, "id") l_page.execute @@ -77,7 +77,7 @@ feature -- HTTP Methods do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -89,19 +89,19 @@ feature -- HTTP Methods do if attached current_user_name (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then if attached {WSF_STRING} req.form_parameter ("method") as l_method then if l_method.is_case_insensitive_equal ("PUT") then do_put (req, res) else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end end else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -116,16 +116,16 @@ feature -- HTTP Methods to_implement ("Check if user has permissions") if attached current_user (req) as l_user then if attached {WSF_STRING} req.path_parameter ("id") as l_id then - if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then + if l_id.is_integer and then attached {CMS_NODE} api.node (l_id.integer_value) as l_node then u_node := extract_data_form (req) u_node.set_id (l_id.integer_value) - api_service.update_node_title (l_user.id,u_node.id, u_node.title) + api.update_node_title (l_user.id,u_node.id, u_node.title) (create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url ("")) else do_error (req, res, l_id) end else - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute end else (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) @@ -139,7 +139,7 @@ feature -- Error local l_page: CMS_RESPONSE do - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) l_page.add_variable (req.absolute_script_url (req.path_info), "request") if a_id.is_integer then -- resource not found diff --git a/cms/src/modules/node/handler/nodes_handler.e b/cms/src/modules/node/handler/nodes_handler.e index 4251f70..651e8e7 100644 --- a/cms/src/modules/node/handler/nodes_handler.e +++ b/cms/src/modules/node/handler/nodes_handler.e @@ -52,8 +52,8 @@ feature -- HTTP Methods -- At the moment the template is hardcoded, but we can -- get them from the configuration file and load them into -- the setup class. - create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup) - l_page.add_variable (api_service.nodes, "nodes") + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) + l_page.add_variable (api.nodes, "nodes") l_page.execute end end diff --git a/cms/src/modules/node/node_module.e b/cms/src/modules/node/node_module.e index e1e59a5..d69e527 100644 --- a/cms/src/modules/node/node_module.e +++ b/cms/src/modules/node/node_module.e @@ -20,47 +20,48 @@ create feature {NONE} -- Initialization - make (a_config: CMS_SETUP) + make (a_setup: CMS_SETUP) -- Create Current module, disabled by default. do name := "node" version := "1.0" description := "Service to manage content based on 'node'" package := "core" - config := a_config + config := a_setup end + config: CMS_SETUP -- Node configuration. feature -- Access: router - router: WSF_ROUTER + router (a_api: CMS_API): WSF_ROUTER -- Node router. do create Result.make (5) - configure_api_node (Result) - configure_api_nodes (Result) - configure_api_node_title (Result) - configure_api_node_summary (Result) - configure_api_node_content (Result) + configure_api_node (a_api, Result) + configure_api_nodes (a_api, Result) + configure_api_node_title (a_api, Result) + configure_api_node_summary (a_api, Result) + configure_api_node_content (a_api, Result) end feature {NONE} -- Implementation: routes - configure_api_node (a_router: WSF_ROUTER) + configure_api_node (api: CMS_API; a_router: WSF_ROUTER) local l_node_handler: NODE_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_node_handler.make (config) + create l_node_handler.make (api) create l_methods l_methods.enable_get l_methods.enable_post l_methods.enable_put a_router.handle_with_request_methods ("/node", l_node_handler, l_methods) - create l_node_handler.make (config) + create l_node_handler.make (api) create l_methods l_methods.enable_get l_methods.enable_post @@ -69,23 +70,23 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/node/{id}", l_node_handler, l_methods) end - configure_api_nodes (a_router: WSF_ROUTER) + configure_api_nodes (api: CMS_API; a_router: WSF_ROUTER) local l_nodes_handler: NODES_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_nodes_handler.make (config) + create l_nodes_handler.make (api) create l_methods l_methods.enable_get a_router.handle_with_request_methods ("/nodes", l_nodes_handler, l_methods) end - configure_api_node_summary (a_router: WSF_ROUTER) + configure_api_node_summary (api: CMS_API; a_router: WSF_ROUTER) local l_report_handler: NODE_SUMMARY_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_report_handler.make (config) + create l_report_handler.make (api) create l_methods l_methods.enable_get l_methods.enable_post @@ -94,12 +95,12 @@ feature {NONE} -- Implementation: routes end - configure_api_node_title (a_router: WSF_ROUTER) + configure_api_node_title (api: CMS_API; a_router: WSF_ROUTER) local l_report_handler: NODE_TITLE_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_report_handler.make (config) + create l_report_handler.make (api) create l_methods l_methods.enable_get l_methods.enable_post @@ -107,12 +108,12 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/node/{id}/title", l_report_handler, l_methods) end - configure_api_node_content (a_router: WSF_ROUTER) + configure_api_node_content (api: CMS_API; a_router: WSF_ROUTER) local l_report_handler: NODE_CONTENT_HANDLER l_methods: WSF_REQUEST_METHODS do - create l_report_handler.make (config) + create l_report_handler.make (api) create l_methods l_methods.enable_get l_methods.enable_post @@ -120,7 +121,6 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods) end - feature -- Hooks register_hooks (a_response: CMS_RESPONSE) @@ -150,7 +150,7 @@ feature -- Hooks menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) local lnk: CMS_LOCAL_LINK - perms: detachable ARRAYED_LIST [READABLE_STRING_8] +-- perms: detachable ARRAYED_LIST [READABLE_STRING_8] do create lnk.make ("List of nodes", "/nodes") a_menu_system.main_menu.extend (lnk) diff --git a/cms/src/service/cms_api_service.e b/cms/src/service/cms_api.e similarity index 55% rename from cms/src/service/cms_api_service.e rename to cms/src/service/cms_api.e index a7d4c8f..877bbf7 100644 --- a/cms/src/service/cms_api_service.e +++ b/cms/src/service/cms_api.e @@ -1,33 +1,86 @@ note - description: "Summary description for {CMS_API_SERVICE}." + description: "Summary description for {CMS_API}." date: "$Date$" revision: "$Revision$" class - CMS_API_SERVICE + CMS_API inherit SHARED_ERROR - REFACTORING_HELPER + REFACTORING_HELPER create make feature -- Initialize - make (a_storage: CMS_STORAGE) + make (a_setup: CMS_SETUP) -- Create the API service with an storege `a_storage'. do - storage := a_storage + setup := a_setup + create error_handler.make + initialize set_successful ensure - storage_set: storage = a_storage +-- storage_set: storage = a_storage + end + + setup: CMS_SETUP + -- CMS setup. + + initialize + local + l_database: DATABASE_CONNECTION + retried: BOOLEAN + l_message: STRING + do + if not retried then + to_implement ("Refactor database setup") + if attached (create {JSON_CONFIGURATION}).new_database_configuration (setup.layout.application_config_path) as l_database_config then + create {DATABASE_CONNECTION_MYSQL} l_database.login_with_connection_string (l_database_config.connection_string) + create {CMS_STORAGE_MYSQL} storage.make (l_database) + else + create {DATABASE_CONNECTION_NULL} l_database.make_common + create {CMS_STORAGE_NULL} storage + end + else + to_implement ("Workaround code, persistence layer does not implement yet this kind of error handling.") + -- error hanling. + create {DATABASE_CONNECTION_NULL} l_database.make_common + create {CMS_STORAGE_NULL} storage + create l_message.make (1024) + if attached ((create {EXCEPTION_MANAGER}).last_exception) as l_exception then + if attached l_exception.description as l_description then + l_message.append (l_description.as_string_32) + l_message.append ("%N%N") + elseif attached l_exception.trace as l_trace then + l_message.append (l_trace) + l_message.append ("%N%N") + else + l_message.append (l_exception.out) + l_message.append ("%N%N") + end + else + l_message.append ("The application crash without available information") + l_message.append ("%N%N") + end + error_handler.add_custom_error (0, " Database Connection ", l_message) + end + rescue + retried := True + retry end feature -- Access + error_handler: ERROR_HANDLER + -- Error handler. + +feature -- Status Report + is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN do Result := storage.is_valid_credential (l_auth_login, l_auth_password) diff --git a/cms/src/service/cms_service.e b/cms/src/service/cms_service.e index 84b67e6..973bc6e 100644 --- a/cms/src/service/cms_service.e +++ b/cms/src/service/cms_service.e @@ -41,11 +41,11 @@ create feature {NONE} -- Initialization - make (a_setup: CMS_SETUP) + make (a_api: CMS_API) -- Build a CMS service with `a_setup' configuration. do - setup := a_setup - configuration := a_setup.configuration + api := a_api + configuration := a_api.setup.configuration initialize end @@ -103,36 +103,41 @@ feature -- Settings: router -- local l_module: CMS_MODULE + l_api: like api + l_router: like router do log.write_debug (generator + ".setup_router") -- Configure root of api handler. - configure_api_root + + l_router := router + configure_api_root (l_router) -- Include routes from modules. + l_api := api across modules as ic loop l_module := ic.item - router.import (l_module.router) + l_router.import (l_module.router (l_api)) end -- Configure files handler. - configure_api_file_handler + configure_api_file_handler (l_router) end - configure_api_root + configure_api_root (a_router: WSF_ROUTER) local l_root_handler: CMS_ROOT_HANDLER l_methods: WSF_REQUEST_METHODS do log.write_debug (generator + ".configure_api_root") - create l_root_handler.make (setup) + create l_root_handler.make (api) create l_methods l_methods.enable_get - router.handle_with_request_methods ("/", l_root_handler, l_methods) - router.handle_with_request_methods ("", l_root_handler, l_methods) + a_router.handle_with_request_methods ("/", l_root_handler, l_methods) + a_router.handle_with_request_methods ("", l_root_handler, l_methods) end - configure_api_file_handler + configure_api_file_handler (a_router: WSF_ROUTER) local fhdl: WSF_FILE_SYSTEM_HANDLER do @@ -143,7 +148,7 @@ feature -- Settings: router do execute_default (ia_req, ia_res) end) - router.handle_with_request_methods ("/", fhdl, router.methods_GET) + a_router.handle_with_request_methods ("/", fhdl, router.methods_GET) end feature -- Execute Filter @@ -162,6 +167,7 @@ feature -- Filters local f, l_filter: detachable WSF_FILTER l_module: CMS_MODULE + l_api: like api do log.write_debug (generator + ".create_filter") l_filter := Void @@ -172,18 +178,19 @@ feature -- Filters l_filter := f -- Error Filter - create {CMS_ERROR_FILTER} f.make (setup) + create {CMS_ERROR_FILTER} f.make (api) f.set_next (l_filter) l_filter := f -- Include filters from modules + l_api := api across modules as ic loop l_module := ic.item if l_module.is_enabled and then - attached l_module.filters as l_m_filters + attached l_module.filters (l_api) as l_m_filters then across l_m_filters as f_ic loop f := f_ic.item @@ -213,11 +220,16 @@ feature -- Filters f.set_next (Current) end - feature -- Access + api: CMS_API + -- API service. + setup: CMS_SETUP -- CMS setup. + do + Result := api.setup + end configuration: CMS_CONFIGURATION -- CMS configuration. diff --git a/cms/src/service/filter/cms_error_filter.e b/cms/src/service/filter/cms_error_filter.e index 6a205e1..2c8c780 100644 --- a/cms/src/service/filter/cms_error_filter.e +++ b/cms/src/service/filter/cms_error_filter.e @@ -20,13 +20,13 @@ feature -- Basic operations execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter do - if not setup.error_handler.has_error then + if not api.error_handler.has_error then log.write_information (generator + ".execute") execute_next (req, res) else - log.write_critical (generator + ".execute" + setup.error_handler.as_string_representation ) - (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup)).execute - setup.error_handler.reset + log.write_critical (generator + ".execute" + api.error_handler.as_string_representation ) + (create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute + api.error_handler.reset end end diff --git a/cms/src/service/handler/cms_handler.e b/cms/src/service/handler/cms_handler.e index c6d2902..9de1552 100644 --- a/cms/src/service/handler/cms_handler.e +++ b/cms/src/service/handler/cms_handler.e @@ -19,20 +19,20 @@ inherit feature {NONE} -- Initialization - make (a_setup: CMS_SETUP) + make (a_api: CMS_API) do - setup := a_setup + api := a_api end feature -- Setup setup: CMS_SETUP + do + Result := api.setup + end feature -- API Service - api_service: CMS_API_SERVICE - do - Result := setup.api_service - end + api: CMS_API end diff --git a/cms/src/service/handler/cms_root_handler.e b/cms/src/service/handler/cms_root_handler.e index 785629f..cf1284d 100644 --- a/cms/src/service/handler/cms_root_handler.e +++ b/cms/src/service/handler/cms_root_handler.e @@ -48,7 +48,7 @@ feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- do - (create {HOME_CMS_RESPONSE}.make (req, res, setup)).execute + (create {HOME_CMS_RESPONSE}.make (req, res, api)).execute end end diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e index c6109bd..6ec8bf8 100644 --- a/cms/src/service/response/cms_response.e +++ b/cms/src/service/response/cms_response.e @@ -15,10 +15,10 @@ inherit feature {NONE} -- Initialization - make(req: WSF_REQUEST; res: WSF_RESPONSE; a_setup: like setup) + make(req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api) do status_code := {HTTP_STATUS_CODE}.ok - setup := a_setup + api := a_api request := req response := res create header.make @@ -56,8 +56,14 @@ feature -- Access response: WSF_RESPONSE + api: CMS_API + -- Current CMS API. + setup: CMS_SETUP - -- Current setup + -- Current setup + do + Result := api.setup + end status_code: INTEGER @@ -222,8 +228,6 @@ feature -- Menu primary_tabs: CMS_MENU do Result := menu_system.primary_tabs - debug - end end feature -- Blocks initialization @@ -378,8 +382,6 @@ feature -- Blocks header_block: CMS_CONTENT_BLOCK local s: STRING - tpl: SMARTY_CMS_PAGE_TEMPLATE - l_page: CMS_HTML_PAGE l_hb: STRING do create s.make_from_string (theme.menu_html (main_menu, True)) diff --git a/cms/src/service/response/home_cms_response.e b/cms/src/service/response/home_cms_response.e index 9cd309c..78e9347 100644 --- a/cms/src/service/response/home_cms_response.e +++ b/cms/src/service/response/home_cms_response.e @@ -21,7 +21,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do Precursor (page) - page.register_variable (setup.api_service.recent_nodes (0, 5), "nodes") + page.register_variable (api.recent_nodes (0, 5), "nodes") end feature -- Execution diff --git a/examples/roc_api/modules/demo/cms_demo_module.e b/examples/roc_api/modules/demo/cms_demo_module.e index bdbe811..4819cd1 100644 --- a/examples/roc_api/modules/demo/cms_demo_module.e +++ b/examples/roc_api/modules/demo/cms_demo_module.e @@ -15,21 +15,17 @@ create feature {NONE} -- Initialization - make (a_config: CMS_SETUP) + make do name := "Demo module" version := "1.0" description := "Service to demonstrate and test cms system" package := "demo" - config := a_config end - config: CMS_SETUP - -- Node configuration. - feature -- Access: router - router: WSF_ROUTER + router (a_api: CMS_API): WSF_ROUTER -- Node router. do create Result.make (2) diff --git a/examples/roc_api/src/ewf_roc_server.e b/examples/roc_api/src/ewf_roc_server.e index 5fd497b..6edeb1b 100644 --- a/examples/roc_api/src/ewf_roc_server.e +++ b/examples/roc_api/src/ewf_roc_server.e @@ -117,12 +117,12 @@ feature -- CMS Initialization initialize_cms (a_setup: CMS_SETUP) local cms: CMS_SERVICE + api: CMS_API do log.write_debug (generator + ".initialize_cms") - setup_modules (a_setup) - - create cms.make (a_setup) + create api.make (a_setup) + create cms.make (api) cms_service := cms end @@ -133,14 +133,13 @@ feature -- CMS setup local m: CMS_MODULE do - create {BASIC_AUTH_MODULE} m.make (a_setup) + create {BASIC_AUTH_MODULE} m.make m.enable a_setup.modules.extend (m) - create {CMS_DEMO_MODULE} m.make (a_setup) + create {CMS_DEMO_MODULE} m.make m.enable a_setup.modules.extend (m) - end setup_storage (a_setup: CMS_SETUP) From abe9de621edc0317b41b866aaff081409a23789f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Nov 2014 14:59:30 +0100 Subject: [PATCH 2/4] Made examples/api compilable. --- examples/api/roc_api.ecf | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/api/roc_api.ecf b/examples/api/roc_api.ecf index a68d4e1..02794df 100644 --- a/examples/api/roc_api.ecf +++ b/examples/api/roc_api.ecf @@ -22,6 +22,7 @@ + From b0930299fcb1248bfb072a59c5862cb39b7c5fd7 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Nov 2014 15:00:00 +0100 Subject: [PATCH 3/4] Fixed assertion violation when DATABASE_NULL is instanciated. --- persistence/implementation/common/database/database_null.e | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence/implementation/common/database/database_null.e b/persistence/implementation/common/database/database_null.e index 9d5dc15..a26437a 100644 --- a/persistence/implementation/common/database/database_null.e +++ b/persistence/implementation/common/database/database_null.e @@ -167,6 +167,7 @@ feature -- LOGIN and DATABASE_APPL only for password_ok password_ok (upasswd: STRING): BOOLEAN -- Can the user password be Void? do + Result := True end password_ensure (name, passwd, uname, upasswd: STRING): BOOLEAN From 96da59c4cb1b9a54816e5ce49ac3630fbfa3742b Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Nov 2014 19:22:01 +0100 Subject: [PATCH 4/4] Added notion of "front" page. Changed CMS_HOOK_BLOCK.get_block_view to accept only attached string for `a_block_id'. Keep simple name in CMS_MENU_SYSTEM. Module that implements a CMS_HOOK need now to redefine CMS_MODULE.register_hooks . Added simple code for NODE_MODULE, in order to see something. Added CMS_URL_UTILITIES that should be used to compute url for cms path such as "/foo/bar". Implemented get_active in CMS_RESPONSE to update the "is_active" on each link. Added NOT_IMPLEMENTED_ERROR_CMS_RESPONSE. Implemented a few hooks in DEMO module, for testing. Updated smarty template related code. --- cms/src/configuration/cms_setup.e | 4 + cms/src/hooks/cms_hook_block.e | 4 +- cms/src/kernel/link/cms_menu_system.e | 24 +- .../modules/basic_auth/basic_auth_module.e | 6 - cms/src/modules/cms_module.e | 2 +- cms/src/modules/node/node_module.e | 34 ++- cms/src/service/cms_api_options.e | 17 ++ cms/src/service/cms_request_util.e | 4 +- cms/src/service/cms_url_utilities.e | 129 +++++++++ cms/src/service/response/cms_response.e | 259 +++++++++++------- .../service/response/error_500_cms_response.e | 4 +- .../not_implemented_error_cms_response.e | 37 +++ cms/src/theme/cms_html_page.e | 11 +- .../smarty_cms_html_page_inspector.e | 10 +- .../smarty_theme/smarty_cms_page_template.e | 9 +- .../modules/demo/cms_demo_module-safe.ecf | 1 + .../roc_api/modules/demo/cms_demo_module.e | 71 ++++- .../site/www/themes/bootstrap/page.tpl | 37 ++- .../www/themes/bootstrap/tpl/page_header.tpl | 3 +- model/src/cms_local_link.e | 8 + 20 files changed, 510 insertions(+), 164 deletions(-) create mode 100644 cms/src/service/cms_api_options.e create mode 100644 cms/src/service/cms_url_utilities.e create mode 100644 cms/src/service/response/not_implemented_error_cms_response.e diff --git a/cms/src/configuration/cms_setup.e b/cms/src/configuration/cms_setup.e index 6659735..58b0e31 100644 --- a/cms/src/configuration/cms_setup.e +++ b/cms/src/configuration/cms_setup.e @@ -45,6 +45,10 @@ feature -- Access: Site files_location: PATH + front_page_path: detachable READABLE_STRING_8 + -- Optional path defining the front page. + -- By default "" or "/". + feature -- Access: Theme themes_location: PATH diff --git a/cms/src/hooks/cms_hook_block.e b/cms/src/hooks/cms_hook_block.e index 54b493a..89d001c 100644 --- a/cms/src/hooks/cms_hook_block.e +++ b/cms/src/hooks/cms_hook_block.e @@ -13,10 +13,12 @@ inherit feature -- Hook block_list: ITERABLE [like {CMS_BLOCK}.name] + -- List of block names, managed by current object. deferred end - get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE) + get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + -- Get block object identified by `a_block_id' and associate with `a_response'. deferred end diff --git a/cms/src/kernel/link/cms_menu_system.e b/cms/src/kernel/link/cms_menu_system.e index 470aba3..5565c5d 100644 --- a/cms/src/kernel/link/cms_menu_system.e +++ b/cms/src/kernel/link/cms_menu_system.e @@ -20,9 +20,9 @@ feature {NONE} -- Initialization do to_implement ("Refactor, take the info from a Database or Configuration file.") create items.make (5) - force (create {CMS_MENU}.make ("primary_nav", 3)) -- primary menu - force (create {CMS_MENU}.make_with_title ("management_nav", "Management", 3)) -- secondary in admin view. - force (create {CMS_MENU}.make_with_title ("secondary_nav", "Navigation", 3)) -- secondary + force (create {CMS_MENU}.make ("primary", 3)) -- primary menu + force (create {CMS_MENU}.make_with_title ("management", "Management", 3)) -- secondary in admin view. + force (create {CMS_MENU}.make_with_title ("secondary", "Navigation", 3)) -- secondary force (create {CMS_MENU}.make_with_title ("user", "User", 3)) -- first_side_bar end @@ -41,18 +41,30 @@ feature -- Access end main_menu: CMS_MENU + obsolete + "Use `primary_menu' [Nov/2014]" do - Result := item ("primary_nav") + Result := primary_menu + end + + primary_menu: CMS_MENU + do + Result := item ("primary") + end + + secondary_menu: CMS_MENU + do + Result := item ("secondary") end management_menu: CMS_MENU do - Result := item ("management_nav") + Result := item ("management") end navigation_menu: CMS_MENU do - Result := item ("secondary_nav") + Result := item ("navigation") end user_menu: CMS_MENU diff --git a/cms/src/modules/basic_auth/basic_auth_module.e b/cms/src/modules/basic_auth/basic_auth_module.e index a198ed7..555d2cb 100644 --- a/cms/src/modules/basic_auth/basic_auth_module.e +++ b/cms/src/modules/basic_auth/basic_auth_module.e @@ -70,10 +70,4 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods) end -feature -- Hooks - - register_hooks (a_response: CMS_RESPONSE) - do - end - end diff --git a/cms/src/modules/cms_module.e b/cms/src/modules/cms_module.e index 6632eba..ce0a9a2 100644 --- a/cms/src/modules/cms_module.e +++ b/cms/src/modules/cms_module.e @@ -33,7 +33,7 @@ feature -- Hooks configuration -- Module hooks configuration. require is_enabled: is_enabled - deferred + do end feature -- Filter diff --git a/cms/src/modules/node/node_module.e b/cms/src/modules/node/node_module.e index d69e527..f5c7349 100644 --- a/cms/src/modules/node/node_module.e +++ b/cms/src/modules/node/node_module.e @@ -9,6 +9,9 @@ class inherit CMS_MODULE + redefine + register_hooks + end CMS_HOOK_MENU_ALTER @@ -68,6 +71,7 @@ feature {NONE} -- Implementation: routes l_methods.enable_put l_methods.enable_delete a_router.handle_with_request_methods ("/node/{id}", l_node_handler, l_methods) + a_router.handle_with_request_methods ("/nodes/", create {WSF_URI_AGENT_HANDLER}.make (agent do_get_nodes (?,?, api)), a_router.methods_get) end configure_api_nodes (api: CMS_API; a_router: WSF_ROUTER) @@ -94,7 +98,6 @@ feature {NONE} -- Implementation: routes a_router.handle_with_request_methods ("/node/{id}/summary", l_report_handler, l_methods) end - configure_api_node_title (api: CMS_API; a_router: WSF_ROUTER) local l_report_handler: NODE_TITLE_HANDLER @@ -134,17 +137,12 @@ feature -- Hooks Result := <<"node-info">> end - get_block_view (a_block_id: detachable READABLE_STRING_8; a_response: CMS_RESPONSE) --- local + get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + local -- b: CMS_CONTENT_BLOCK do --- if --- a_execution.is_front and then --- attached a_execution.user as u --- then --- create b.make ("node-info", "Node", "Node ...", a_execution.formats.plain_text) --- a_execution.add_block (b, Void) --- end +-- create b.make (a_block_id, "Block::node", "This is a block test", Void) +-- a_response.add_block (b, "sidebar_second") end menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) @@ -152,8 +150,20 @@ feature -- Hooks lnk: CMS_LOCAL_LINK -- perms: detachable ARRAYED_LIST [READABLE_STRING_8] do - create lnk.make ("List of nodes", "/nodes") - a_menu_system.main_menu.extend (lnk) + create lnk.make ("List of nodes", a_response.url ("/nodes", Void)) + a_menu_system.primary_menu.extend (lnk) + end + +feature -- Handler + + do_get_nodes (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API) + local + r: CMS_RESPONSE + do + create {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE} r.make (req, res, a_api) + r.set_main_content ("Sorry: listing the CMS nodes is not yet implemented.") + r.add_block (create {CMS_CONTENT_BLOCK}.make ("nodes_warning", Void, "/nodes/ is not yet implemented", Void), "highlighted") + r.execute end end diff --git a/cms/src/service/cms_api_options.e b/cms/src/service/cms_api_options.e new file mode 100644 index 0000000..1a5dc6e --- /dev/null +++ b/cms/src/service/cms_api_options.e @@ -0,0 +1,17 @@ +note + description: "Summary description for {CMS_API_OPTIONS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CMS_API_OPTIONS + +inherit + WSF_API_OPTIONS + +create + make, + make_from_manifest + +end diff --git a/cms/src/service/cms_request_util.e b/cms/src/service/cms_request_util.e index e9e26c8..e6a1be6 100644 --- a/cms/src/service/cms_request_util.e +++ b/cms/src/service/cms_request_util.e @@ -9,6 +9,8 @@ deferred class inherit + CMS_ENCODERS + REFACTORING_HELPER feature -- User @@ -21,8 +23,6 @@ feature -- User if attached {CMS_USER} current_user (req) as l_user then Result := l_user.name end - - end current_user (req: WSF_REQUEST): detachable CMS_USER diff --git a/cms/src/service/cms_url_utilities.e b/cms/src/service/cms_url_utilities.e new file mode 100644 index 0000000..8fff472 --- /dev/null +++ b/cms/src/service/cms_url_utilities.e @@ -0,0 +1,129 @@ +note + description: "Summary description for {CMS_URL_UTILITIES}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_URL_UTILITIES + +inherit + CMS_REQUEST_UTIL + +feature -- Core + + site_url: READABLE_STRING_8 + deferred + end + + base_url: detachable READABLE_STRING_8 + -- Base url if any. + deferred + end + + based_path (p: STRING): STRING + -- Path `p' in the context of the `base_url' + do + if attached base_url as l_base_url then + create Result.make_from_string (l_base_url) + if p.is_empty then + else + if p[1] = '/' then + Result.append (p.substring (2, p.count)) + else + Result.append (p) + end + end + else + Result := p + end + end + +feature -- Url + + absolute_url (a_path: STRING; opts: detachable CMS_API_OPTIONS): STRING + local + l_opts: detachable CMS_API_OPTIONS + do + l_opts := opts + if l_opts = Void then + create l_opts.make (1) + end + l_opts.force (True, "absolute") + Result := url (a_path, l_opts) + end + + url (a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING + -- URL for path `a_path' and optional parameters from `opts'. + --| Options `opts' could be + --| - absolute: True|False => return absolute url + --| - query: string => append "?query" + --| - fragment: string => append "#fragment" + local + q,f: detachable STRING_8 + l_abs: BOOLEAN + do + l_abs := False + + if opts /= Void then + l_abs := opts.boolean_item ("absolute", l_abs) + if attached opts.item ("query") as l_query then + if attached {READABLE_STRING_8} l_query as s_value then + q := s_value + elseif attached {ITERABLE [TUPLE [key, value: READABLE_STRING_GENERAL]]} l_query as lst then + create q.make_empty + across + lst as c + loop + if q.is_empty then + else + q.append_character ('&') + end + q.append (url_encoded (c.item.key)) + q.append_character ('=') + q.append (url_encoded (c.item.value)) + end + end + end + if attached opts.string_item ("fragment") as s_frag then + f := s_frag + end + end + if l_abs then + if a_path.substring_index ("://", 1) = 0 then + create Result.make_from_string (site_url) + if a_path.is_empty then + elseif Result.ends_with ("/") then + if a_path[1] = '/' then + Result.append_string (a_path.substring (2, a_path.count)) + else + Result.append_string (a_path) + end + else + if a_path[1] = '/' then + Result.append_string (a_path) + else + Result.append_character ('/') + Result.append_string (a_path) + end + end + else + Result := a_path + end + else + Result := based_path (a_path) + end + if q /= Void then + Result.append ("?" + q) + end + if f /= Void then + Result.append ("#" + f) + end + end + + checked_url (a_url: READABLE_STRING_8): READABLE_STRING_8 + do + Result := a_url + end + +end diff --git a/cms/src/service/response/cms_response.e b/cms/src/service/response/cms_response.e index 6ec8bf8..14894ab 100644 --- a/cms/src/service/response/cms_response.e +++ b/cms/src/service/response/cms_response.e @@ -7,15 +7,13 @@ deferred class CMS_RESPONSE inherit - CMS_ENCODERS - - CMS_REQUEST_UTIL + CMS_URL_UTILITIES REFACTORING_HELPER feature {NONE} -- Initialization - make(req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api) + make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api) do status_code := {HTTP_STATUS_CODE}.ok api := a_api @@ -79,6 +77,36 @@ feature -- Access additional_page_head_lines: detachable LIST [READABLE_STRING_8] -- HTML>head>...extra lines +feature -- URL utilities + + is_front: BOOLEAN + -- Is current response related to "front" page? + local + l_path_info: READABLE_STRING_8 + do + l_path_info := request.path_info + if attached setup.front_page_path as l_front_page_path then + Result := l_front_page_path.same_string (l_path_info) + else + if attached base_url as l_base_url then + Result := l_path_info.same_string (l_base_url) + else + Result := l_path_info.is_empty or else l_path_info.same_string ("/") + end + end + end + + site_url: READABLE_STRING_8 + do + Result := absolute_host (request, "") + end + + base_url: detachable READABLE_STRING_8 + -- Base url if any. + --| Usually it is Void, but it could be + --| /project/demo/ + --| FIXME: for now, no way to change that. Always at the root "/" + feature -- Access: CMS site_name: STRING_32 @@ -94,6 +122,8 @@ feature -- Access: CMS values: CMS_VALUE_TABLE -- Associated values indexed by string name. + + feature -- Permission -- FIXME: to be implemented has_permissions and has_permission. @@ -206,8 +236,15 @@ feature -- Menu menu_system: CMS_MENU_SYSTEM main_menu: CMS_MENU + obsolete + "Use `primary_menu' [Nov/2014]" do - Result := menu_system.main_menu + Result := primary_menu + end + + primary_menu: CMS_MENU + do + Result := menu_system.primary_menu end management_menu: CMS_MENU @@ -323,7 +360,6 @@ feature -- Blocks if attached navigation_menu_block as l_block then add_block (l_block, "first_sidebar") end - if attached user_menu_block as l_block then add_block (l_block, "first_sidebar") end @@ -335,9 +371,9 @@ feature -- Blocks hook_block_view end - main_menu_block: detachable CMS_MENU_BLOCK + primary_menu_block: detachable CMS_MENU_BLOCK do - if attached main_menu as m and then not m.is_empty then + if attached primary_menu as m and then not m.is_empty then create Result.make (m) end end @@ -384,17 +420,17 @@ feature -- Blocks s: STRING l_hb: STRING do - create s.make_from_string (theme.menu_html (main_menu, True)) + create s.make_from_string (theme.menu_html (primary_menu, True)) create l_hb.make_empty create Result.make ("header", Void, l_hb, formats.full_html) Result.set_is_raw (True) end - horizontal_main_menu_html: STRING + horizontal_primary_menu_html: STRING do create Result.make_empty Result.append ("
") - Result.append (theme.menu_html (main_menu, True)) + Result.append (theme.menu_html (primary_menu, True)) Result.append ("
") end @@ -564,11 +600,15 @@ feature -- Hook: block feature -- Menu: change add_to_main_menu (lnk: CMS_LINK) + obsolete + "use add_to_primary_menu [Nov/2014]" do --- if attached {CMS_LOCAL_LINK} lnk as l_local then --- l_local.get_is_active (request) --- end - main_menu.extend (lnk) + add_to_primary_menu (lnk) + end + + add_to_primary_menu (lnk: CMS_LINK) + do + add_to_menu (lnk, primary_menu) end add_to_menu (lnk: CMS_LINK; m: CMS_MENU) @@ -646,7 +686,7 @@ feature -- Message feature -- Theme theme: CMS_THEME - -- Current theme + -- Current theme get_theme local @@ -681,106 +721,112 @@ feature -- Generation prepare (page: CMS_HTML_PAGE) do + -- Menu + add_to_primary_menu (create {CMS_LOCAL_LINK}.make ("Home", "/")) + call_menu_alter_hooks (menu_system) + prepare_menu_system (menu_system) + + -- Blocks + get_blocks + across + regions as reg_ic + loop + across + reg_ic.item.blocks as ic + loop + if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then + recursive_get_active (l_menu_block.menu, request) + end + end + end + + -- Values common_prepare (page) custom_prepare (page) - -- Menu - add_to_main_menu (create {CMS_LOCAL_LINK}.make ("Home", "/")) - call_menu_alter_hooks (menu_system) - prepare_menu_system (menu_system) + -- Cms values + call_value_alter_hooks (values) - -- Blocks - get_blocks + -- Predefined values + page.register_variable (page, "page") -- DO NOT REMOVE + + -- Values Associated with current Execution object. + across + values as ic + loop + page.register_variable (ic.item, ic.key) + end + + -- Block rendering + across + regions as reg_ic + loop across - regions as reg_ic + reg_ic.item.blocks as ic loop - across - reg_ic.item.blocks as ic - loop - if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then - recursive_get_active (l_menu_block.menu, request) - end - end + page.add_to_region (theme.block_html (ic.item), reg_ic.item.name) end + end - -- Values - if attached current_user_name (request) as l_user then - page.register_variable (l_user, "user") - end - - -- Cms values - call_value_alter_hooks (values) - - - -- Predefined values - if attached title as l_title then - page.set_title (l_title) - else - page.set_title ("CMS::" + request.path_info) - end - page.register_variable (page, "page") - - -- page.register_variable (is_front, "is_front") - page.register_variable (request.absolute_script_url (""), "site_url") - page.register_variable (title, "site_title") - -- page.register_variable (site_name_and_slogan, "site_name_and_slogan") - -- if attached logo_location as l_logo then - -- page.register_variable (l_logo, "logo") - -- end - page.register_variable (horizontal_main_menu_html, "primary_nav") - - -- Values Associated with current Execution object. + -- Additional lines in + if attached additional_page_head_lines as l_head_lines then across - values as ic + l_head_lines as hl loop - page.register_variable (ic.item, ic.key) + page.head_lines.force (hl.item) end - - -- Block rendering - across - regions as reg_ic - loop - across - reg_ic.item.blocks as ic - loop - page.add_to_region (theme.block_html (ic.item), reg_ic.item.name) - end - end - - -- Additional lines in - if attached additional_page_head_lines as l_head_lines then - across - l_head_lines as hl - loop - page.head_lines.force (hl.item) - end - end - - end - - common_prepare (page: CMS_HTML_PAGE) - do - fixme ("Fix generacion common") - page.register_variable (request.absolute_script_url (""), "host") - page.register_variable (setup.is_web, "web") - page.register_variable (setup.is_html, "html") - if attached current_user_name (request) as l_user then - page.register_variable (l_user, "user") end end + common_prepare (page: CMS_HTML_PAGE) + -- Common preparation for page `page'. + do + fixme ("Fix generation common") + + -- Information + page.set_title (title) + debug ("cms") + if title = Void then + page.set_title ("CMS::" + request.path_info) --| FIXME: probably, should be removed and handled by theme. + end + end + + -- Variables + page.register_variable (request.absolute_script_url (""), "site_url") + page.register_variable (request.absolute_script_url (""), "host") -- Same as `site_url'. + if attached current_user_name (request) as l_user then + page.register_variable (l_user, "user") + end + page.register_variable (title, "site_title") + page.set_is_front (is_front) + + -- Variables/Setup + page.register_variable (setup.is_web, "web") + page.register_variable (setup.is_html, "html") + + -- Variables/Misc + +-- FIXME: logo .. could be a settings of theme, managed by admin front-end/database. +-- if attached logo_location as l_logo then +-- page.register_variable (l_logo, "logo") +-- end + + -- Menu... + page.register_variable (horizontal_primary_menu_html, "primary_nav") + end + custom_prepare (page: CMS_HTML_PAGE) + -- Common preparation for page `page' that can be redefined by descendants. do end - prepare_menu_system (a_menu_system: CMS_MENU_SYSTEM) do --- across --- a_menu_system as c --- loop --- prepare_links (c.item) --- end + across + a_menu_system as c + loop + prepare_links (c.item) + end end prepare_links (a_menu: CMS_LINK_COMPOSITE) @@ -796,7 +842,7 @@ feature -- Generation -- to_remove.force (lm) -- else -- if lm.permission_arguments is Void , this is permitted --- lm.get_is_active (request) + get_local_link_active_status (lm) if attached {CMS_LINK_COMPOSITE} lm as comp then prepare_links (comp) end @@ -823,7 +869,7 @@ feature -- Generation loop ln := ic.item if attached {CMS_LOCAL_LINK} ln as l_local then --- l_local.get_is_active (request) + get_local_link_active_status (l_local) end if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then recursive_get_active (l_comp, req) @@ -832,6 +878,23 @@ feature -- Generation end end + get_local_link_active_status (a_lnk: CMS_LOCAL_LINK) + -- Get `a_lnk.is_active' value according to `request' data. + local + qs: STRING + l_is_active: BOOLEAN + do + create qs.make_from_string (request.percent_encoded_path_info) + l_is_active := qs.same_string (a_lnk.location) + if not l_is_active then + if attached request.query_string as l_query_string and then not l_query_string.is_empty then + qs.append_character ('?') + qs.append (l_query_string) + end + l_is_active := qs.same_string (a_lnk.location) + end + a_lnk.set_is_active (l_is_active) + end feature -- Custom Variables diff --git a/cms/src/service/response/error_500_cms_response.e b/cms/src/service/response/error_500_cms_response.e index 24c908e..7bfea99 100644 --- a/cms/src/service/response/error_500_cms_response.e +++ b/cms/src/service/response/error_500_cms_response.e @@ -21,8 +21,8 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do page.register_variable (request.absolute_script_url (request.path_info), "request") - page.register_variable ("500", "code") - page.set_status_code (500) + page.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) + page.register_variable (page.status_code.out, "code") end feature -- Execution diff --git a/cms/src/service/response/not_implemented_error_cms_response.e b/cms/src/service/response/not_implemented_error_cms_response.e new file mode 100644 index 0000000..2d37558 --- /dev/null +++ b/cms/src/service/response/not_implemented_error_cms_response.e @@ -0,0 +1,37 @@ +note + description: "Summary description for {NOT_IMPLEMENTED_ERROR_CMS_RESPONSE}." + date: "$Date$" + revision: "$Revision$" + +class + NOT_IMPLEMENTED_ERROR_CMS_RESPONSE + +inherit + + CMS_RESPONSE + redefine + custom_prepare + end + +create + make + +feature -- Generation + + custom_prepare (page: CMS_HTML_PAGE) + do + page.register_variable (request.absolute_script_url (request.path_info), "request") + page.register_variable ("501", "code") + page.set_status_code (501) + end + +feature -- Execution + + process + -- Computed response message. + do + set_title ("Not Implemented") + set_page_title (Void) + end +end + diff --git a/cms/src/theme/cms_html_page.e b/cms/src/theme/cms_html_page.e index 1565d07..3b06281 100644 --- a/cms/src/theme/cms_html_page.e +++ b/cms/src/theme/cms_html_page.e @@ -38,7 +38,9 @@ feature -- Access -- Optional page type. -- such as "front", "about", ... that could be customized by themes. - title: detachable STRING + is_front: BOOLEAN + + title: detachable READABLE_STRING_32 language: STRING @@ -59,6 +61,7 @@ feature -- Access feature -- Status + status_code: INTEGER feature -- Header @@ -87,6 +90,12 @@ feature -- Region feature -- Element change + set_is_front (b: BOOLEAN) + -- Set `is_front' to `b'. + do + is_front := b + end + register_variable (a_value: detachable ANY; k: READABLE_STRING_GENERAL) do variables.force (a_value, k) diff --git a/cms/src/theme/smarty_theme/smarty_cms_html_page_inspector.e b/cms/src/theme/smarty_theme/smarty_cms_html_page_inspector.e index 45d57c8..cbe3c4a 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_html_page_inspector.e +++ b/cms/src/theme/smarty_theme/smarty_cms_html_page_inspector.e @@ -13,6 +13,8 @@ inherit internal_data end + CMS_ENCODERS + create register @@ -29,7 +31,13 @@ feature {TEMPLATE_ROUTINES} if attached l_page.variables.item (l_fn) as v then Result := cell_of (v) elseif l_fn.is_case_insensitive_equal ("title") then - Result := cell_of (l_page.title) + if attached l_page.title as l_title then + Result := cell_of (html_encoded (l_title)) + else + Result := cell_of (Void) + end + elseif l_fn.is_case_insensitive_equal ("is_front") then + Result := cell_of (l_page.is_front) elseif l_fn.starts_with_general ("region_") then l_fn.remove_head (7) -- remove "region_" Result := cell_of (l_page.region (l_fn)) diff --git a/cms/src/theme/smarty_theme/smarty_cms_page_template.e b/cms/src/theme/smarty_theme/smarty_cms_page_template.e index 188a743..d5b45ab 100644 --- a/cms/src/theme/smarty_theme/smarty_cms_page_template.e +++ b/cms/src/theme/smarty_theme/smarty_cms_page_template.e @@ -9,6 +9,8 @@ class inherit CMS_PAGE_TEMPLATE + CMS_ENCODERS + SHARED_TEMPLATE_CONTEXT create @@ -41,12 +43,13 @@ feature -- Access variables.force (ic.item, ic.key) end + -- FIXME: review variables ! if attached page.title as l_title then - variables.force (l_title, "page_title") - variables.force (l_title, "head_title") + variables.force (html_encoded (l_title), "head_title") + variables.force (html_encoded (l_title), "page_title") else + variables.force ("CMS", "head_title") variables.force ("", "page_title") - variables.force ("", "head_title") end variables.force (page.language, "language") diff --git a/examples/roc_api/modules/demo/cms_demo_module-safe.ecf b/examples/roc_api/modules/demo/cms_demo_module-safe.ecf index dd678f2..a954561 100644 --- a/examples/roc_api/modules/demo/cms_demo_module-safe.ecf +++ b/examples/roc_api/modules/demo/cms_demo_module-safe.ecf @@ -12,6 +12,7 @@ + diff --git a/examples/roc_api/modules/demo/cms_demo_module.e b/examples/roc_api/modules/demo/cms_demo_module.e index 4819cd1..879a064 100644 --- a/examples/roc_api/modules/demo/cms_demo_module.e +++ b/examples/roc_api/modules/demo/cms_demo_module.e @@ -9,6 +9,13 @@ class inherit CMS_MODULE + redefine + register_hooks + end + + CMS_HOOK_MENU_ALTER + + CMS_HOOK_BLOCK create make @@ -30,20 +37,63 @@ feature -- Access: router do create Result.make (2) - map_uri_template_agent (Result, "/demo/", agent handle_demo) - map_uri_template_agent (Result, "/book/{id}", agent handle_demo_entry) + map_uri_template_agent (Result, "/demo/", agent handle_demo (?,?,a_api)) + map_uri_template_agent (Result, "/demo/{id}", agent handle_demo_entry (?,?,a_api)) + end + +feature -- Hooks + + register_hooks (a_response: CMS_RESPONSE) + do + a_response.add_menu_alter_hook (Current) + a_response.add_block_hook (Current) + end + + block_list: ITERABLE [like {CMS_BLOCK}.name] + do + Result := <<"demo-info">> + end + + get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + local + b: CMS_CONTENT_BLOCK + mb: CMS_MENU_BLOCK + m: CMS_MENU + lnk: CMS_LOCAL_LINK + do + if a_block_id.is_case_insensitive_equal_general ("demo-info") then + if a_response.request.request_uri.starts_with ("/demo/") then + create m.make_with_title (a_block_id, "Demo", 2) + create lnk.make ("/demo/abc", a_response.url ("/demo/abc", Void)) + m.extend (lnk) + create lnk.make ("/demo/123", a_response.url ("/demo/123", Void)) + m.extend (lnk) + create mb.make (m) + a_response.add_block (mb, "sidebar_second") + end + end + end + + menu_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) + local + lnk: CMS_LOCAL_LINK +-- perms: detachable ARRAYED_LIST [READABLE_STRING_8] + do + create lnk.make ("Demo", "/demo/") + a_menu_system.primary_menu.extend (lnk) end feature -- Handler handle_demo, - handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE) + handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API) local - m: WSF_NOT_FOUND_RESPONSE + r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE do - create m.make (req) - m.set_body ("Not yet implemented!") - res.send (m) + 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") + r.execute end feature -- Mapping helper: uri template @@ -86,11 +136,4 @@ feature -- Mapping helper: uri template agent map_uri_template_with_request_methods (a_router, a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) end - -feature -- Hooks - - register_hooks (a_response: CMS_RESPONSE) - do - end - end diff --git a/examples/roc_api/site/www/themes/bootstrap/page.tpl b/examples/roc_api/site/www/themes/bootstrap/page.tpl index 1b4566c..53f29fd 100644 --- a/examples/roc_api/site/www/themes/bootstrap/page.tpl +++ b/examples/roc_api/site/www/themes/bootstrap/page.tpl @@ -21,11 +21,11 @@ -{$page_title/} +{$head_title/} - {if isset="$top"} + {if isset="$region_top"} {$region_top/} {/if} @@ -35,40 +35,47 @@
- + + {unless empty="$page.region_sidebar_first"} +
+ {$page.region_sidebar_first/} +
+ {/unless} - - {$region_sidebar_first/}
- {$region_highlighted/} + {$page.region_highlighted/} - - {$region_help/} - + {$page.region_help/} - {$region_main/} + {unless empty="$page_title"}

{$page_title/}

{/unless} + {$page.region_content/}
- - {$region_sidebar_second/} + + {unless empty="$page.region_sidebar_second"} +
+ {$page.region_sidebar_second/} +
+ {/unless} +
- {$region_footer/} + {$page.region_footer/} - {$region_bottom/} + {$page.region_bottom/}