From 85ac9f73660643da58ed0fbcb3e60a65b894f43d Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Apr 2017 18:30:27 +0200 Subject: [PATCH 1/3] Cosmetic. --- modules/auth/cms_authentication_module.e | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index f6b450a..781fd2d 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -481,7 +481,8 @@ feature -- Handler r.set_status_code ({HTTP_CONSTANTS}.internal_server_error) r.set_main_content ("

ERROR: User activation failed for " + html_encoded (l_user.name) + "!

") end - else -- the token does not exist, or it was already used. + else + -- the token does not exist, or it was already used. r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.set_main_content ("

The token " + l_token.value + " is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "

") end From 3dc478b4a0d993cede5e8a8c0f65d381c07400d8 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Apr 2017 21:51:41 +0200 Subject: [PATCH 2/3] Fixed user registration activation workflow. - Fixed new user insertion in SQL database. - Removed temp user when activated. - Renamed local variable names related to temp users. - More information when error occurs during user registration. --- modules/auth/cms_authentication_module.e | 42 +++++++++++-------- src/persistence/user/cms_user_storage_i.e | 21 ++++------ src/persistence/user/cms_user_storage_sql_i.e | 41 +++++++++--------- src/service/user/cms_user_api.e | 39 +++++++++-------- 4 files changed, 72 insertions(+), 71 deletions(-) diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index 781fd2d..148864e 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -445,44 +445,52 @@ feature -- Handler l_user_api: CMS_USER_API l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE es: CMS_AUTHENTICATION_EMAIL_SERVICE + l_temp_id: INTEGER_64 do - l_user_api := api.user_api - create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if r.has_permission ("account activate") then + if api.has_permission ("account activate") then + l_user_api := api.user_api if attached {WSF_STRING} req.path_parameter ("token") as l_token then - if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_user then + if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_temp_user then -- TODO copy the personal information --! to CMS_USER_PROFILE and persist data --! check also CMS_USER.data_items - -- Valid user_id - l_user.set_id (0) - l_user.mark_active - l_user_api.new_user_from_temp_user (l_user) + l_temp_id := l_temp_user.id + -- Valid user_id + l_temp_user.set_id (0) + l_temp_user.mark_active + l_user_api.new_user_from_temp_user (l_temp_user) + + create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) if not l_user_api.has_error and then - attached l_user_api.user_by_name (l_user.name) as l_new_user + attached l_user_api.user_by_name (l_temp_user.name) as l_new_user then -- Delete temporal User - l_user_api.delete_temp_user (l_user) + l_temp_user.set_id (l_temp_id) + l_user_api.delete_temp_user (l_temp_user) l_user_api.remove_activation (l_token.value) - r.set_main_content ("

The account " + html_encoded (l_user.name) + " has been activated

") + r.set_main_content ("

The account " + html_encoded (l_new_user.name) + " has been activated

") -- Send Email - if attached l_user.email as l_email then + if attached l_new_user.email as l_email then create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) write_debug_log (generator + ".handle register: send_contact_activation_confirmation_email") - es.send_contact_activation_confirmation_email (l_email, l_user, req.absolute_script_url ("")) + es.send_contact_activation_confirmation_email (l_email, l_new_user, req.absolute_script_url ("")) end else -- Failure!!! r.set_status_code ({HTTP_CONSTANTS}.internal_server_error) - r.set_main_content ("

ERROR: User activation failed for " + html_encoded (l_user.name) + "!

") + r.set_main_content ("

ERROR: User activation failed for " + html_encoded (l_temp_user.name) + "!

") + if attached l_user_api.error_handler.as_single_error as err then + r.add_error_message (html_encoded (err.string_representation)) + end end - else - -- the token does not exist, or it was already used. + else -- the token does not exist, or it was already used. + create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) + r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.set_main_content ("

The token " + l_token.value + " is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "

") end @@ -493,7 +501,7 @@ feature -- Handler end else create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) - r.execute + r.execute end end diff --git a/src/persistence/user/cms_user_storage_i.e b/src/persistence/user/cms_user_storage_i.e index 3b77ab2..35914fe 100644 --- a/src/persistence/user/cms_user_storage_i.e +++ b/src/persistence/user/cms_user_storage_i.e @@ -241,7 +241,6 @@ feature -- Access: Temp Users password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void) end - temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER -- User with activation token `a_token', if any. deferred @@ -254,19 +253,15 @@ feature -- Access: Temp Users deferred end - token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING -- Retrieve activation token for user identified with id `a_id', if any. deferred end - feature -- New Temp User - new_user_from_temp_user (a_user: CMS_TEMP_USER) - -- new user from temporal user `a_user' - require - no_id: not a_user.has_id + new_user_from_temp_user (a_temp_user: CMS_TEMP_USER) + -- new user from temporal user `a_temp_user' deferred end @@ -275,17 +270,17 @@ feature -- New Temp User deferred end - new_temp_user (a_user: CMS_TEMP_USER) - -- New temp user `a_user'. + new_temp_user (a_temp_user: CMS_TEMP_USER) + -- New temp user `a_temp_user'. require - no_id: not a_user.has_id + no_id: not a_temp_user.has_id deferred end - delete_temp_user (a_user: CMS_TEMP_USER) - -- Delete user `a_user'. + delete_temp_user (a_temp_user: CMS_TEMP_USER) + -- Delete user `a_temp_user'. require - has_id: a_user.has_id + has_id: a_temp_user.has_id deferred end diff --git a/src/persistence/user/cms_user_storage_sql_i.e b/src/persistence/user/cms_user_storage_sql_i.e index 0f68cf3..f3f2cf4 100644 --- a/src/persistence/user/cms_user_storage_sql_i.e +++ b/src/persistence/user/cms_user_storage_sql_i.e @@ -217,13 +217,14 @@ feature -- Change: user l_password_hash := l_security.password_hash (l_password, l_password_salt) write_information_log (generator + ".new_user") - create l_parameters.make (4) + create l_parameters.make (7) l_parameters.put (a_user.name, "name") l_parameters.put (l_password_hash, "password") l_parameters.put (l_password_salt, "salt") l_parameters.put (l_email, "email") l_parameters.put (create {DATE_TIME}.make_now_utc, "created") l_parameters.put (a_user.status, "status") + l_parameters.put (a_user.profile_name, "profile_name") sql_insert (sql_insert_user, l_parameters) if not error_handler.has_error then @@ -1231,33 +1232,31 @@ feature {NONE} -- Implementation: User feature -- New Temp User - new_user_from_temp_user (a_user: CMS_TEMP_USER) + new_user_from_temp_user (a_temp_user: CMS_TEMP_USER) -- local l_parameters: STRING_TABLE [detachable ANY] do error_handler.reset if - attached a_user.hashed_password as l_password_hash and then - attached a_user.email as l_email and then - attached a_user.salt as l_password_salt + attached a_temp_user.hashed_password as l_password_hash and then + attached a_temp_user.email as l_email and then + attached a_temp_user.salt as l_password_salt then -- FIXME: store the personal_information in profile! sql_begin_transaction write_information_log (generator + ".new_user_from_temp_user") - create l_parameters.make (6) - l_parameters.put (a_user.name, "name") + create l_parameters.make (7) + l_parameters.put (a_temp_user.name, "name") l_parameters.put (l_password_hash, "password") l_parameters.put (l_password_salt, "salt") l_parameters.put (l_email, "email") l_parameters.put (create {DATE_TIME}.make_now_utc, "created") - l_parameters.put (a_user.status, "status") + l_parameters.put (a_temp_user.status, "status") + l_parameters.put (a_temp_user.profile_name, "profile_name") sql_insert (sql_insert_user, l_parameters) - if not error_handler.has_error then - a_user.set_id (last_inserted_user_id) - end if not error_handler.has_error then sql_commit_transaction else @@ -1270,8 +1269,8 @@ feature -- New Temp User end end - new_temp_user (a_user: CMS_TEMP_USER) - -- Add a new temp_user `a_user'. + new_temp_user (a_temp_user: CMS_TEMP_USER) + -- Add a new temp_user `a_temp_user'. local l_parameters: STRING_TABLE [detachable ANY] l_password_salt, l_password_hash: STRING @@ -1279,9 +1278,9 @@ feature -- New Temp User do error_handler.reset if - attached a_user.password as l_password and then - attached a_user.email as l_email and then - attached a_user.personal_information as l_personal_information + attached a_temp_user.password as l_password and then + attached a_temp_user.email as l_email and then + attached a_temp_user.personal_information as l_personal_information then create l_security @@ -1290,7 +1289,7 @@ feature -- New Temp User write_information_log (generator + ".new_temp_user") create l_parameters.make (4) - l_parameters.put (a_user.name, "name") + l_parameters.put (a_temp_user.name, "name") l_parameters.put (l_password_hash, "password") l_parameters.put (l_password_salt, "salt") l_parameters.put (l_email, "email") @@ -1299,7 +1298,7 @@ feature -- New Temp User sql_begin_transaction sql_insert (sql_insert_temp_user, l_parameters) if not error_handler.has_error then - a_user.set_id (last_inserted_temp_user_id) + a_temp_user.set_id (last_inserted_temp_user_id) sql_commit_transaction else sql_rollback_transaction @@ -1328,8 +1327,8 @@ feature -- Remove Activation sql_finalize end - delete_temp_user (a_user: CMS_TEMP_USER) - -- Delete user `a_user'. + delete_temp_user (a_temp_user: CMS_TEMP_USER) + -- Delete user `a_temp_user'. local l_parameters: STRING_TABLE [detachable ANY] do @@ -1337,7 +1336,7 @@ feature -- Remove Activation sql_begin_transaction write_information_log (generator + ".delete_temp_user") create l_parameters.make (1) - l_parameters.put (a_user.id, "uid") + l_parameters.put (a_temp_user.id, "uid") sql_modify (sql_delete_temp_user, l_parameters) sql_commit_transaction sql_finalize diff --git a/src/service/user/cms_user_api.e b/src/service/user/cms_user_api.e index 5a22917..76ca1dc 100644 --- a/src/service/user/cms_user_api.e +++ b/src/service/user/cms_user_api.e @@ -454,38 +454,37 @@ feature -- Access - Temp User feature -- Change Temp User - new_user_from_temp_user (a_user: CMS_TEMP_USER) - -- Add a new user `a_user'. + new_user_from_temp_user (a_temp_user: CMS_TEMP_USER) + -- Add a new user `a_temp_user'. require - no_id: not a_user.has_id - has_hashed_password: a_user.hashed_password /= Void - has_sal: a_user.salt /= Void + has_hashed_password: a_temp_user.hashed_password /= Void + has_sal: a_temp_user.salt /= Void do reset_error if - attached a_user.hashed_password as l_password and then - attached a_user.salt as l_salt and then - attached a_user.email as l_email + attached a_temp_user.hashed_password as l_password and then + attached a_temp_user.salt as l_salt and then + attached a_temp_user.email as l_email then - storage.new_user_from_temp_user (a_user) + storage.new_user_from_temp_user (a_temp_user) error_handler.append (storage.error_handler) else error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!") end end - new_temp_user (a_user: CMS_TEMP_USER) - -- Add a new user `a_user'. + new_temp_user (a_temp_user: CMS_TEMP_USER) + -- Add a new user `a_temp_user'. require - no_id: not a_user.has_id - no_hashed_password: a_user.hashed_password = Void + no_id: not a_temp_user.has_id + no_hashed_password: a_temp_user.hashed_password = Void do reset_error if - attached a_user.password as l_password and then - attached a_user.email as l_email + attached a_temp_user.password as l_password and then + attached a_temp_user.email as l_email then - storage.new_temp_user (a_user) + storage.new_temp_user (a_temp_user) error_handler.append (storage.error_handler) else error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!") @@ -498,13 +497,13 @@ feature -- Change Temp User storage.remove_activation (a_token) end - delete_temp_user (a_user: CMS_TEMP_USER) - -- Delete user `a_user'. + delete_temp_user (a_temp_user: CMS_TEMP_USER) + -- Delete user `a_temp_user'. require - has_id: a_user.has_id + has_id: a_temp_user.has_id do reset_error - storage.delete_temp_user (a_user) + storage.delete_temp_user (a_temp_user) error_handler.append (storage.error_handler) end From 1f6fce1278b3d8eda8d04a71c4706fd1b91a163e Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 11 Apr 2017 11:56:04 +0200 Subject: [PATCH 3/3] Improved theming for admin vs site. - Added $theme_path, $base_path - Added CMS_RESPONSE.module_resource_url (...) instead of using hardcoded "/module/" + name + ... - Use base_path rather than base_url (note ROC CMS is not yet working with EWF standalone "base" url option) --- .../modules/messaging/files/css/messaging.css | 1 - .../messaging/files/scss/messaging.scss | 1 - examples/demo/site/themes/bootstrap/page.tpl | 6 +- .../admin/cms_admin_module_administration.e | 2 +- modules/auth/cms_authentication_module.e | 2 +- modules/blog/cms_blog_module.e | 2 +- modules/comments/cms_comments_module.e | 2 +- modules/contact/src/cms_contact_module.e | 6 +- .../feed_aggregator/feed_aggregator_module.e | 2 +- modules/files/cms_files_module.e | 8 +- modules/messaging/src/cms_messaging_module.e | 6 +- modules/node/cms_node_module.e | 2 +- modules/taxonomy/cms_taxonomy_module.e | 2 +- modules/wikitext/wikitext_module.e | 2 +- src/configuration/cms_setup.e | 24 +++++- src/service/cms_api.e | 73 +++++++++++++++++-- src/service/cms_execution.e | 12 +-- .../handler/cms_theme_file_system_handler.e | 59 +++++++++++++++ src/service/response/cms_response.e | 26 ++++++- 19 files changed, 198 insertions(+), 40 deletions(-) create mode 100644 src/service/handler/cms_theme_file_system_handler.e diff --git a/examples/demo/site/modules/messaging/files/css/messaging.css b/examples/demo/site/modules/messaging/files/css/messaging.css index 5633f3e..561ec9b 100644 --- a/examples/demo/site/modules/messaging/files/css/messaging.css +++ b/examples/demo/site/modules/messaging/files/css/messaging.css @@ -1,5 +1,4 @@ .messaging-box fieldset { - resize: both; display: flex; flex-wrap: wrap; align-items: flex-start; diff --git a/examples/demo/site/modules/messaging/files/scss/messaging.scss b/examples/demo/site/modules/messaging/files/scss/messaging.scss index 86131b5..1a7d32d 100644 --- a/examples/demo/site/modules/messaging/files/scss/messaging.scss +++ b/examples/demo/site/modules/messaging/files/scss/messaging.scss @@ -1,6 +1,5 @@ .messaging-box { fieldset { - resize: both; display: flex; flex-wrap: wrap; align-items: flex-start; diff --git a/examples/demo/site/themes/bootstrap/page.tpl b/examples/demo/site/themes/bootstrap/page.tpl index e31018d..3871b3c 100644 --- a/examples/demo/site/themes/bootstrap/page.tpl +++ b/examples/demo/site/themes/bootstrap/page.tpl @@ -4,11 +4,11 @@ - + - - + + {if isset="$head"}{$head/}{/if} {if isset="$styles"}{$styles/}{/if} diff --git a/modules/admin/cms_admin_module_administration.e b/modules/admin/cms_admin_module_administration.e index 047b0fc..8d33b0e 100644 --- a/modules/admin/cms_admin_module_administration.e +++ b/modules/admin/cms_admin_module_administration.e @@ -133,7 +133,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) -- do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/admin.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/admin.css", Void), Void) end menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index 148864e..83311aa 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -1157,7 +1157,7 @@ feature -- Response Alter response_alter (a_response: CMS_RESPONSE) do a_response.add_javascript_url ("https://www.google.com/recaptcha/api.js") - a_response.add_style (a_response.url ("/module/" + name + "/files/css/auth.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/auth.css", Void), Void) end feature {NONE} -- Implementation diff --git a/modules/blog/cms_blog_module.e b/modules/blog/cms_blog_module.e index 4b8ac7f..6aa3b52 100644 --- a/modules/blog/cms_blog_module.e +++ b/modules/blog/cms_blog_module.e @@ -139,7 +139,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/blog.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/blog.css", Void), Void) end menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) diff --git a/modules/comments/cms_comments_module.e b/modules/comments/cms_comments_module.e index 5e734ba..6e69f99 100644 --- a/modules/comments/cms_comments_module.e +++ b/modules/comments/cms_comments_module.e @@ -90,7 +90,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/comments.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/comments.css", Void), Void) end end diff --git a/modules/contact/src/cms_contact_module.e b/modules/contact/src/cms_contact_module.e index 4dfef99..6db9fa3 100644 --- a/modules/contact/src/cms_contact_module.e +++ b/modules/contact/src/cms_contact_module.e @@ -186,7 +186,7 @@ feature -- Hooks l_tpl_block.set_value (l_recaptcha_site_key, "recaptcha_site_key") end a_response.add_block (l_tpl_block, "content") - a_response.add_style (a_response.url ("/module/" + name + "/files/css/contact.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/contact.css", Void), Void) else debug ("cms") a_response.add_warning_message ("Error with block [" + a_block_id + "]") @@ -200,7 +200,7 @@ feature -- Hooks local f: CMS_FORM do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/contact.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/contact.css", Void), Void) if attached smarty_template_block (Current, "contact", api) as l_tpl_block then if attached recaptcha_site_key (api) as l_recaptcha_site_key then l_tpl_block.set_value (l_recaptcha_site_key, "recaptcha_site_key") @@ -281,7 +281,7 @@ feature -- Hooks do write_information_log (generator + ".handle_post_contact") create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - r.add_style (r.url ("/module/" + name + "/files/css/contact.css", Void), Void) + r.add_style (r.module_resource_url (Current, "/files/css/contact.css", Void), Void) r.values.force (False, "has_error") create vars.make_caseless (5) diff --git a/modules/feed_aggregator/feed_aggregator_module.e b/modules/feed_aggregator/feed_aggregator_module.e index d6d5160..60a335a 100644 --- a/modules/feed_aggregator/feed_aggregator_module.e +++ b/modules/feed_aggregator/feed_aggregator_module.e @@ -326,7 +326,7 @@ feature -- Hook response_alter (a_response: CMS_RESPONSE) do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/feed_aggregator.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/feed_aggregator.css", Void), Void) end menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) diff --git a/modules/files/cms_files_module.e b/modules/files/cms_files_module.e index b48c3a5..98df481 100644 --- a/modules/files/cms_files_module.e +++ b/modules/files/cms_files_module.e @@ -146,7 +146,7 @@ feature -- Handler create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) -- add style - r.add_style (r.url ("/module/" + name + "/files/css/files.css", Void), Void) + r.add_style (r.module_resource_url (Current, "/files/css/files.css", Void), Void) create body.make_empty @@ -245,7 +245,7 @@ feature -- Handler body.append ("

Upload files

%N") -- set style - r.add_style (r.url ("/module/" + name + "/files/css/files.css", Void), Void) + r.add_style (r.module_resource_url (Current, "/files/css/files.css", Void), Void) if api.has_permission (upload_files_permission) then body.append ("

Please choose file(s) to upload.

") @@ -269,8 +269,8 @@ feature -- Handler body.append ("Use advanced file uploading.%N") else -- add JS for dropzone - r.add_javascript_url (r.url ("/module/" + name + "/files/js/dropzone.js", Void)) - r.add_style (r.url ("/module/" + name + "/files/js/dropzone.css", Void), Void) + r.add_javascript_url (r.module_resource_url (Current, "/files/js/dropzone.js", Void)) + r.add_style (r.module_resource_url (Current, "/files/js/dropzone.css", Void), Void) -- create form to choose files and upload them body.append ("
") diff --git a/modules/messaging/src/cms_messaging_module.e b/modules/messaging/src/cms_messaging_module.e index 2bbec23..b0f589d 100644 --- a/modules/messaging/src/cms_messaging_module.e +++ b/modules/messaging/src/cms_messaging_module.e @@ -109,7 +109,7 @@ feature -- Hooks local f: CMS_FORM do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/messaging.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/messaging.css", Void), Void) -- TODO: use template to overwrite/customize -- if attached smarty_template_block (Current, "messaging", api) as l_tpl_block then -- across @@ -215,7 +215,7 @@ $(document).ready(function() { }); }); - ]") + ]") Result := f end @@ -249,7 +249,7 @@ $(document).ready(function() { do if api.has_permission ("message any user") then create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - r.add_style (r.url ("/module/" + name + "/files/css/messaging.css", Void), Void) + r.add_style (r.module_resource_url (Current, "/files/css/messaging.css", Void), Void) create s.make_empty diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e index 386f820..a0d2ba7 100644 --- a/modules/node/cms_node_module.e +++ b/modules/node/cms_node_module.e @@ -224,7 +224,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) -- do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/node.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/node.css", Void), Void) end block_list: ITERABLE [like {CMS_BLOCK}.name] diff --git a/modules/taxonomy/cms_taxonomy_module.e b/modules/taxonomy/cms_taxonomy_module.e index a61745d..1d43832 100644 --- a/modules/taxonomy/cms_taxonomy_module.e +++ b/modules/taxonomy/cms_taxonomy_module.e @@ -147,7 +147,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/taxonomy.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/taxonomy.css", Void), Void) end end diff --git a/modules/wikitext/wikitext_module.e b/modules/wikitext/wikitext_module.e index 80bda1f..3c16e0a 100644 --- a/modules/wikitext/wikitext_module.e +++ b/modules/wikitext/wikitext_module.e @@ -64,7 +64,7 @@ feature -- Hooks response_alter (a_response: CMS_RESPONSE) do - a_response.add_style (a_response.url ("/module/" + name + "/files/css/wikitext.css", Void), Void) + a_response.add_style (a_response.module_resource_url (Current, "/files/css/wikitext.css", Void), Void) end end diff --git a/src/configuration/cms_setup.e b/src/configuration/cms_setup.e index 8f10e0f..e2220fb 100644 --- a/src/configuration/cms_setup.e +++ b/src/configuration/cms_setup.e @@ -99,7 +99,7 @@ feature {NONE} -- Initialization end -- Selected theme's name - site_theme_name := text_item_or_default ("theme", "default") + site_theme_name := text_item_or_default ("site.theme", "default") set_theme (site_theme_name) -- Administration @@ -325,6 +325,18 @@ feature -- Settings is_debug: BOOLEAN -- Is debug mode enabled? + set_site_mode + -- Switch to site mode. + --| - Change theme + --| - .. + do + if is_theme_valid (site_theme_name) then + set_theme (site_theme_name) + else + -- Keep previous theme! + end + end + set_administration_mode -- Switch to administration mode. --| - Change theme @@ -341,7 +353,7 @@ feature -- Settings -- Set theme to `a_name`. do theme_name := a_name.as_string_32 - theme_location := themes_location.extended (theme_name) + theme_location := theme_location_for (theme_name) end feature -- Query @@ -417,7 +429,7 @@ feature -- Access: theme local fu: FILE_UTILITIES do - Result := fu.directory_path_exists (themes_location.extended (a_theme_name)) + Result := fu.directory_path_exists (theme_location_for (a_theme_name)) end theme_information_location: PATH @@ -437,6 +449,12 @@ feature -- Access: theme -- Default: same as site theme. -- TODO: change to builtin "admin" theme? + theme_location_for (a_theme_name: READABLE_STRING_GENERAL): PATH + -- Theme directory location for theme `a_theme_name`. + do + Result := themes_location.extended (a_theme_name) + end + feature -- Access mailer: NOTIFICATION_MAILER diff --git a/src/service/cms_api.e b/src/service/cms_api.e index ea5aca5..57c0946 100644 --- a/src/service/cms_api.e +++ b/src/service/cms_api.e @@ -116,6 +116,7 @@ feature {NONE} -- Initialize initialize_site_url -- Initialize site and base url. local + l_base_url: detachable READABLE_STRING_8 l_url: detachable STRING_8 i,j: INTEGER do @@ -134,12 +135,23 @@ feature {NONE} -- Initialize if i > 0 then j := l_url.index_of ('/', i + 3) if j > 0 then - base_url := l_url.substring (j, l_url.count) + l_base_url := l_url.substring (j, l_url.count) end end + if l_base_url /= Void then + base_url := l_base_url + if l_base_url.ends_with_general ("/") then + create base_path.make_from_string (l_base_url) + else + create base_path.make_from_string (l_base_url + "/") + end + else + create base_path.make_from_string ("/") + end ensure site_url_set: site_url /= Void site_url_ends_with_slash: site_url.ends_with_general ("/") + base_path_set: base_path /= Void and then base_path.ends_with_general ("/") end initialize_content_types @@ -380,6 +392,9 @@ feature -- Access: url --| Usually it is Void, but it could be --| /project/demo/ + base_path: IMMUTABLE_STRING_8 + -- Base path, default to "/" + site_url: IMMUTABLE_STRING_8 -- Site url @@ -493,10 +508,20 @@ feature -- Helpers: html links feature -- Settings + switch_to_site_mode + do + if is_administration_mode then + setup.set_site_mode + is_administration_mode := False + end + end + switch_to_administration_mode do - setup.set_administration_mode - is_administration_mode := True + if not is_administration_mode then + setup.set_administration_mode + is_administration_mode := True + end end is_administration_mode: BOOLEAN @@ -1101,6 +1126,14 @@ feature -- Environment/ theme Result := setup.files_location end + files_path: STRING_8 + do + create Result.make_from_string (base_path) + Result.append ("files/") + ensure + ends_with_slash: Result.ends_with ("/") + end + cache_location: PATH -- CMS internal cache location. do @@ -1118,16 +1151,44 @@ feature -- Environment/ theme Result := setup.theme_name end + theme_path: STRING_8 + -- URL path to the theme. + do + Result := theme_path_for (theme_name) + ensure + ends_with_slash: Result.ends_with ("/") + end + theme_assets_location: PATH -- assets (js, css, images, etc). do - debug ("refactor_fixme") - fixme ("Check if we really need it") - end -- Check how to get this path from the CMS_THEME information. Result := theme_location.extended ("assets") end +feature -- Theming path helpers + + theme_location_for (a_theme_name: READABLE_STRING_GENERAL): PATH + do + Result := setup.theme_location_for (a_theme_name) + end + + theme_path_for (a_theme_name: READABLE_STRING_GENERAL): STRING_8 + -- URL path to the theme `a_theme_name`. + do + create Result.make_from_string (base_path) + Result.append ("theme/") + Result.append (url_encoded (a_theme_name)) + Result.append_character ('/') + ensure + ends_with_slash: Result.ends_with ("/") + end + + theme_assets_location_for (a_theme_name: READABLE_STRING_GENERAL): PATH + do + Result := theme_location_for (a_theme_name).extended ("assets") + end + feature -- Environment/ module module_configuration (a_module: CMS_MODULE; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER diff --git a/src/service/cms_execution.e b/src/service/cms_execution.e index 48720eb..bcac24c 100644 --- a/src/service/cms_execution.e +++ b/src/service/cms_execution.e @@ -195,16 +195,17 @@ feature -- Settings: router configure_api_file_handler (a_router: WSF_ROUTER) local fhdl: WSF_FILE_SYSTEM_HANDLER + themehdl: CMS_THEME_FILE_SYSTEM_HANDLER do api.logger.put_information (generator + ".configure_api_file_handler", Void) - create fhdl.make_hidden_with_path (api.theme_assets_location) - fhdl.disable_index - fhdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE) + create themehdl.make (api) + themehdl.set_not_found_handler (agent (ia_uri: READABLE_STRING_8; ia_req: WSF_REQUEST; ia_res: WSF_RESPONSE) do execute_default (ia_req, ia_res) end) - a_router.handle ("/theme/", fhdl, router.methods_GET) + -- See CMS_API.api.theme_path_for (...) for the hardcoded "/theme/" path. + a_router.handle ("/theme/{theme_id}{/vars}", themehdl, router.methods_GET) -- "/files/.." create fhdl.make_hidden_with_path (api.files_location) @@ -213,7 +214,7 @@ feature -- Settings: router do execute_default (ia_req, ia_res) end) - a_router.handle ("/files/", fhdl, router.methods_GET) + a_router.handle (api.files_path, fhdl, router.methods_GET) -- files folder from specific module. a_router.handle ("/module/{modname}/files{/vars}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_module_files), a_router.methods_get) @@ -244,6 +245,7 @@ feature -- Request execution initialize_site_execution -- Initialize for site execution. do + api.switch_to_site_mode api.initialize_execution setup_router end diff --git a/src/service/handler/cms_theme_file_system_handler.e b/src/service/handler/cms_theme_file_system_handler.e new file mode 100644 index 0000000..f599ce1 --- /dev/null +++ b/src/service/handler/cms_theme_file_system_handler.e @@ -0,0 +1,59 @@ +note + description: "Summary description for {CMS_THEME_FILE_SYSTEM_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CMS_THEME_FILE_SYSTEM_HANDLER + +inherit + WSF_URI_TEMPLATE_HANDLER + +create + make + +feature -- Initialization + + make (a_cms_api: CMS_API) + do + api := a_cms_api + end + + api: CMS_API + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute `req' responding in `res'. + local + fhdl: WSF_FILE_SYSTEM_HANDLER + not_found: NOT_FOUND_ERROR_CMS_RESPONSE + do + if attached {WSF_STRING} req.path_parameter ("theme_id") as l_theme_id then + create fhdl.make_hidden_with_path (api.theme_assets_location_for (l_theme_id.value)) + fhdl.disable_index + fhdl.set_not_found_handler (not_found_handler) + fhdl.execute_starts_with (api.theme_path_for (l_theme_id.value), req, res) +-- a_router.handle (api.theme_path, fhdl, router.methods_GET) + elseif attached not_found_handler as h then + h.call (req.percent_encoded_path_info, req, res) + else + create not_found.make (req, res, api) + not_found.execute + end + end + +feature -- Not found handling + + not_found_handler: detachable PROCEDURE [READABLE_STRING_8, WSF_REQUEST, WSF_RESPONSE] + + set_not_found_handler (h: like not_found_handler) + do + not_found_handler := h + end + +note + copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 8dba680..810195f 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -25,7 +25,10 @@ feature {NONE} -- Initialization create header.make create values.make (3) site_url := a_api.site_url - base_url := a_api.base_url + if attached a_api.base_url as l_base_url then + base_url := l_base_url + end + base_path := a_api.base_path initialize end @@ -124,8 +127,8 @@ feature -- URL utilities 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) + if base_path.same_string (l_path_info) then + Result := True else Result := l_path_info.is_empty or else l_path_info.same_string ("/") end @@ -134,12 +137,18 @@ feature -- URL utilities site_url: IMMUTABLE_STRING_8 -- Absolute site url. + -- Always ends with '/' base_url: detachable IMMUTABLE_STRING_8 -- Base url if any. --| Usually it is Void, but it could be --| /project/demo/ + base_path: IMMUTABLE_STRING_8 + -- Base path, default to "/". + -- Always ends with '/' + -- Could be /project/demo/ + feature -- Access: CMS site_name: STRING_32 @@ -1242,6 +1251,7 @@ feature -- Generation -- Variables page.register_variable (absolute_url ("", Void), "site_url") + page.register_variable (base_path, "base_path") page.register_variable (absolute_url ("", Void), "host") -- Same as `site_url'. page.register_variable (request.is_https, "is_https") if attached title as l_title then @@ -1253,6 +1263,8 @@ feature -- Generation page.set_is_https (request.is_https) -- Variables/Misc + page.register_variable (is_administration_mode, "is_administration_mode") + page.register_variable (api.theme_path, "theme_path") -- FIXME: logo .. could be a settings of theme, managed by admin front-end/database. -- if attached logo_location as l_logo then @@ -1398,6 +1410,14 @@ feature -- Helpers: URLs Result := api.location_url (a_location, opts) end + module_resource_url (a_module: CMS_MODULE; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8 + -- Url for resource `a_path` associated with module `a_module`. + require + a_valid_valid: a_path.is_empty or else a_path.starts_with ("/") + do + Result := url ("/module/" + a_module.name + a_path, opts) + end + user_url (u: CMS_USER): like url require u_with_id: u.has_id