Refactor directory structrue
This commit is contained in:
306
library/src/configuration/cms_configuration.e
Normal file
306
library/src/configuration/cms_configuration.e
Normal file
@@ -0,0 +1,306 @@
|
||||
note
|
||||
description: "[
|
||||
Configure the basic settings for a CMS application,
|
||||
i.e: where to look for themes, name of the application, etc...
|
||||
|
||||
The settings can be configured by default:
|
||||
- using the current working directory,
|
||||
- using the commands provided by the class
|
||||
- or by an external configuration file.
|
||||
]"
|
||||
|
||||
class
|
||||
CMS_CONFIGURATION
|
||||
|
||||
inherit
|
||||
ANY
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_layout: CMS_LAYOUT)
|
||||
-- Initialize `Current' with layout `a_layout'.
|
||||
do
|
||||
layout := a_layout
|
||||
create options.make_equal (10)
|
||||
configuration_location := layout.cms_config_ini_path
|
||||
import_from_path (layout.cms_config_ini_path)
|
||||
analyze
|
||||
end
|
||||
|
||||
analyze
|
||||
do
|
||||
get_root_location
|
||||
get_var_location
|
||||
get_themes_location
|
||||
get_files_location
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
|
||||
configuration_location: detachable PATH
|
||||
-- Path to configuration location.
|
||||
|
||||
option (a_name: READABLE_STRING_GENERAL): detachable ANY
|
||||
do
|
||||
Result := options.item (a_name)
|
||||
end
|
||||
|
||||
options: STRING_TABLE [STRING_32]
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
append_to_string (s: STRING)
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
s.append ("Options:%N")
|
||||
across
|
||||
options as c
|
||||
loop
|
||||
s.append (c.key.to_string_8)
|
||||
s.append_character ('=')
|
||||
utf.string_32_into_utf_8_string_8 (c.item, s)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
|
||||
s.append ("Specific:%N")
|
||||
s.append ("root_location=" + root_location.utf_8_name + "%N")
|
||||
s.append ("var_location=" + var_location.utf_8_name + "%N")
|
||||
s.append ("files_location=" + files_location.utf_8_name + "%N")
|
||||
s.append ("themes_location=" + themes_location.utf_8_name + "%N")
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_option (a_name: READABLE_STRING_GENERAL; a_value: STRING_32)
|
||||
do
|
||||
options.force (a_value, a_name.as_string_8)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
var_location: PATH
|
||||
|
||||
root_location: PATH
|
||||
|
||||
files_location: PATH
|
||||
|
||||
themes_location: PATH
|
||||
|
||||
theme_name (dft: detachable like theme_name): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("theme") as s then
|
||||
Result := s
|
||||
elseif dft /= Void then
|
||||
Result := dft
|
||||
else
|
||||
Result := "default"
|
||||
end
|
||||
end
|
||||
|
||||
site_id: READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.id") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := "_EWF_CMS_NO_ID_"
|
||||
end
|
||||
end
|
||||
|
||||
site_name (dft: like site_name): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.name") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
site_url (dft: like site_url): detachable READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.url") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
if Result /= Void then
|
||||
if Result.is_empty then
|
||||
-- ok
|
||||
elseif not Result.ends_with ("/") then
|
||||
Result := Result + "/"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
site_script_url (dft: like site_script_url): detachable READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.script_url") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
if Result /= Void then
|
||||
if Result.is_empty then
|
||||
elseif not Result.ends_with ("/") then
|
||||
Result := Result + "/"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
site_email (dft: like site_email): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.email") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
get_var_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("var-dir") as s then
|
||||
create var_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
var_location := execution_environment.current_working_path
|
||||
end
|
||||
end
|
||||
|
||||
get_root_location
|
||||
do
|
||||
root_location := layout.www_path
|
||||
end
|
||||
|
||||
get_files_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("files-dir") as s then
|
||||
create files_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
create files_location.make_from_string ("files")
|
||||
end
|
||||
end
|
||||
|
||||
get_themes_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("themes-dir") as s then
|
||||
create themes_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
themes_location := root_location.extended ("themes")
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
import_from_file (fn: READABLE_STRING_GENERAL)
|
||||
do
|
||||
import_from_path (create {PATH}.make_from_string (fn))
|
||||
end
|
||||
|
||||
import_from_path (a_filename: PATH)
|
||||
-- Import ini file content
|
||||
local
|
||||
f: PLAIN_TEXT_FILE
|
||||
l,v: STRING_8
|
||||
p: INTEGER
|
||||
do
|
||||
create f.make_with_path (a_filename)
|
||||
if f.exists and f.is_readable then
|
||||
f.open_read
|
||||
from
|
||||
f.read_line
|
||||
until
|
||||
f.exhausted
|
||||
loop
|
||||
l := f.last_string
|
||||
l.left_adjust
|
||||
if not l.is_empty then
|
||||
if l[1] = '#' then
|
||||
-- commented line
|
||||
else
|
||||
p := l.index_of ('=', 1)
|
||||
if p > 1 then
|
||||
v := l.substring (p + 1, l.count)
|
||||
l.keep_head (p - 1)
|
||||
v.left_adjust
|
||||
v.right_adjust
|
||||
l.right_adjust
|
||||
|
||||
if l.is_case_insensitive_equal ("@include") then
|
||||
import_from_file (resolved_string (v))
|
||||
else
|
||||
set_option (l.as_lower, resolved_string (v))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
f.read_line
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Environment
|
||||
|
||||
resolved_string (s: READABLE_STRING_8): STRING_32
|
||||
-- Resolved `s' using `options' or else environment variables.
|
||||
local
|
||||
i,n,b,e: INTEGER
|
||||
k: detachable READABLE_STRING_8
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
create Result.make (s.count)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if i + 1 < n and then s[i] = '$' and then s[i+1] = '{' then
|
||||
b := i + 2
|
||||
e := s.index_of ('}', b) - 1
|
||||
if e > 0 then
|
||||
k := s.substring (b, e)
|
||||
if attached option (k) as v then
|
||||
if attached {READABLE_STRING_32} v as s32 then
|
||||
Result.append (s32)
|
||||
else
|
||||
Result.append (v.out)
|
||||
end
|
||||
i := e + 1
|
||||
elseif attached execution_environment.item (k) as v then
|
||||
Result.append (v)
|
||||
i := e + 1
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
layout: CMS_LAYOUT
|
||||
-- Cms layout
|
||||
end
|
||||
15
library/src/configuration/cms_custom_setup.e
Normal file
15
library/src/configuration/cms_custom_setup.e
Normal file
@@ -0,0 +1,15 @@
|
||||
note
|
||||
description: "Summary description for {CMS_CUSTOM_SETUP}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_CUSTOM_SETUP
|
||||
|
||||
inherit
|
||||
CMS_DEFAULT_SETUP
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
end
|
||||
113
library/src/configuration/cms_default_setup.e
Normal file
113
library/src/configuration/cms_default_setup.e
Normal file
@@ -0,0 +1,113 @@
|
||||
note
|
||||
description: "Summary description for {CMS_DEFAULT_SETUP}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_DEFAULT_SETUP
|
||||
|
||||
inherit
|
||||
CMS_SETUP
|
||||
|
||||
REFACTORING_HELPER
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_layout: CMS_LAYOUT)
|
||||
-- Create a default setup with `a_layout'.
|
||||
do
|
||||
layout := a_layout
|
||||
create configuration.make (layout)
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize varius cms components.
|
||||
do
|
||||
configure
|
||||
create modules.make (3)
|
||||
build_mailer
|
||||
initialize_modules
|
||||
end
|
||||
|
||||
configure
|
||||
do
|
||||
site_id := configuration.site_id
|
||||
site_url := configuration.site_url (Void)
|
||||
site_name := configuration.site_name ("EWF::CMS")
|
||||
site_email := configuration.site_email ("webmaster")
|
||||
themes_location := configuration.themes_location
|
||||
theme_name := configuration.theme_name ("default")
|
||||
|
||||
compute_theme_location
|
||||
compute_theme_resource_location
|
||||
end
|
||||
|
||||
initialize_modules
|
||||
-- Intialize core modules.
|
||||
local
|
||||
m: CMS_MODULE
|
||||
do
|
||||
-- -- Core
|
||||
-- create {USER_MODULE} m.make (Current)
|
||||
-- m.enable
|
||||
-- modules.extend (m)
|
||||
|
||||
-- create {ADMIN_MODULE} m.make (Current)
|
||||
-- m.enable
|
||||
-- modules.extend (m)
|
||||
|
||||
create {NODE_MODULE} m.make (Current)
|
||||
m.enable
|
||||
modules.extend (m)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
modules: CMS_MODULE_COLLECTION
|
||||
-- <Precursor>
|
||||
|
||||
is_html: BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
-- Enable change the mode
|
||||
Result := (create {CMS_JSON_CONFIGURATION}).is_html_mode(layout.application_config_path)
|
||||
end
|
||||
|
||||
is_web: BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := (create {CMS_JSON_CONFIGURATION}).is_web_mode(layout.application_config_path)
|
||||
|
||||
end
|
||||
|
||||
build_auth_engine
|
||||
do
|
||||
to_implement ("Not implemented authentication")
|
||||
end
|
||||
|
||||
build_mailer
|
||||
do
|
||||
to_implement ("Not implemented mailer")
|
||||
end
|
||||
|
||||
feature -- Compute location
|
||||
|
||||
compute_theme_location
|
||||
do
|
||||
theme_location := themes_location.extended (theme_name)
|
||||
end
|
||||
|
||||
compute_theme_resource_location
|
||||
-- assets (js, css, images, etc)
|
||||
-- Not used at the moment.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Check if we really need it")
|
||||
end
|
||||
theme_resource_location := theme_location
|
||||
end
|
||||
|
||||
end
|
||||
47
library/src/configuration/cms_json_configuration.e
Normal file
47
library/src/configuration/cms_json_configuration.e
Normal file
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "Summary description for {CMS_JSON_CONFIGURATION}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_JSON_CONFIGURATION
|
||||
|
||||
|
||||
inherit
|
||||
|
||||
JSON_CONFIGURATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
is_html_mode (a_path: PATH): BOOLEAN
|
||||
-- Is the server running on web mode?
|
||||
local
|
||||
l_parser: JSON_PARSER
|
||||
do
|
||||
if attached json_file_from (a_path) as json_file then
|
||||
l_parser := new_json_parser (json_file)
|
||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
||||
attached {JSON_OBJECT} jv.item ("server") as l_server and then
|
||||
attached {JSON_STRING} l_server.item ("mode") as l_mode then
|
||||
Result := l_mode.item.is_case_insensitive_equal_general ("html")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
is_web_mode (a_path: PATH): BOOLEAN
|
||||
-- Is the server running on web mode?
|
||||
local
|
||||
l_parser: JSON_PARSER
|
||||
do
|
||||
if attached json_file_from (a_path) as json_file then
|
||||
l_parser := new_json_parser (json_file)
|
||||
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
|
||||
attached {JSON_OBJECT} jv.item ("server") as l_server and then
|
||||
attached {JSON_STRING} l_server.item ("mode") as l_mode then
|
||||
Result := l_mode.item.is_case_insensitive_equal_general ("web")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
59
library/src/configuration/cms_layout.e
Normal file
59
library/src/configuration/cms_layout.e
Normal file
@@ -0,0 +1,59 @@
|
||||
note
|
||||
description: "[
|
||||
CMS Layout providing file system locations for
|
||||
- config
|
||||
- application
|
||||
- logs
|
||||
- documentation
|
||||
- themes
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_LAYOUT
|
||||
|
||||
inherit
|
||||
|
||||
APPLICATION_LAYOUT
|
||||
|
||||
create
|
||||
make_default,
|
||||
make_with_path
|
||||
|
||||
|
||||
feature -- Access
|
||||
|
||||
theme_path: PATH
|
||||
-- Directory for templates (HTML, etc).
|
||||
local
|
||||
p: detachable PATH
|
||||
do
|
||||
p := internal_theme_path
|
||||
if p = Void then
|
||||
p := www_path.extended ("theme")
|
||||
internal_theme_path := p
|
||||
end
|
||||
Result := p
|
||||
end
|
||||
|
||||
cms_config_ini_path: PATH
|
||||
-- Database Configuration file path.
|
||||
local
|
||||
p: detachable PATH
|
||||
do
|
||||
p := internal_cms_config_ini_path
|
||||
if p = Void then
|
||||
p := config_path.extended ("cms.ini")
|
||||
internal_cms_config_ini_path := p
|
||||
end
|
||||
Result := p
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_theme_path: detachable like theme_path
|
||||
|
||||
internal_cms_config_ini_path: detachable like cms_config_ini_path
|
||||
|
||||
end
|
||||
69
library/src/configuration/cms_setup.e
Normal file
69
library/src/configuration/cms_setup.e
Normal file
@@ -0,0 +1,69 @@
|
||||
note
|
||||
description: "Class that enable to set basic configuration, application layout, core modules and themes."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_SETUP
|
||||
|
||||
feature -- Access
|
||||
|
||||
configuration: CMS_CONFIGURATION
|
||||
-- cms configuration.
|
||||
|
||||
layout: CMS_LAYOUT
|
||||
-- CMS layout.
|
||||
|
||||
is_html: BOOLEAN
|
||||
-- api with progressive enhancements css and js, server side rendering.
|
||||
deferred
|
||||
end
|
||||
|
||||
is_web: BOOLEAN
|
||||
-- web: Web Site with progressive enhancements css and js and Ajax calls.
|
||||
deferred
|
||||
end
|
||||
|
||||
modules: CMS_MODULE_COLLECTION
|
||||
-- List of available modules.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: Site
|
||||
|
||||
site_id: READABLE_STRING_8
|
||||
|
||||
site_name: READABLE_STRING_32
|
||||
-- Name of the site.
|
||||
|
||||
site_email: READABLE_STRING_8
|
||||
-- Email for the site.
|
||||
|
||||
site_url: detachable READABLE_STRING_8
|
||||
-- Optional base url of the site.
|
||||
|
||||
front_page_path: detachable READABLE_STRING_8
|
||||
-- Optional path defining the front page.
|
||||
-- By default "" or "/".
|
||||
|
||||
feature -- Access: Theme
|
||||
|
||||
themes_location: PATH
|
||||
-- Path to themes.
|
||||
|
||||
theme_location: PATH
|
||||
-- Path to a particular theme.
|
||||
|
||||
theme_resource_location: PATH
|
||||
-- Path to a particular theme resource.
|
||||
|
||||
theme_information_location: PATH
|
||||
-- theme informations.
|
||||
do
|
||||
Result := theme_location.extended ("theme.info")
|
||||
end
|
||||
|
||||
theme_name: READABLE_STRING_32
|
||||
-- theme name.
|
||||
|
||||
end
|
||||
11
library/src/hooks/cms_hook.e
Normal file
11
library/src/hooks/cms_hook.e
Normal file
@@ -0,0 +1,11 @@
|
||||
note
|
||||
description: "[
|
||||
Marker interface for CMS Hook
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK
|
||||
|
||||
end
|
||||
35
library/src/hooks/cms_hook_auto_register.e
Normal file
35
library/src/hooks/cms_hook_auto_register.e
Normal file
@@ -0,0 +1,35 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {CMS_HOOK_AUTO_REGISTER}.
|
||||
When inheriting from this class, the declared hooks are automatically
|
||||
registered, otherwise, each descendant has to add it to the cms service
|
||||
itself.
|
||||
]"
|
||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||
revision: "$Revision: 95708 $"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
feature -- Hook
|
||||
|
||||
auto_subscribe_to_hooks (a_response: CMS_RESPONSE)
|
||||
do
|
||||
if attached {CMS_HOOK_MENU_SYSTEM_ALTER} Current as h_menu_system_alter then
|
||||
a_response.subscribe_to_menu_system_alter_hook (h_menu_system_alter)
|
||||
end
|
||||
if attached {CMS_HOOK_MENU_ALTER} Current as h_menu_alter then
|
||||
a_response.subscribe_to_menu_alter_hook (h_menu_alter)
|
||||
end
|
||||
if attached {CMS_HOOK_BLOCK} Current as h_block then
|
||||
a_response.subscribe_to_block_hook (h_block)
|
||||
end
|
||||
if attached {CMS_HOOK_FORM_ALTER} Current as h_form then
|
||||
a_response.subscribe_to_form_alter_hook (h_form)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
24
library/src/hooks/cms_hook_block.e
Normal file
24
library/src/hooks/cms_hook_block.e
Normal file
@@ -0,0 +1,24 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HOOK_BLOCK}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
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: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
-- Get block object identified by `a_block_id' and associate with `a_response'.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
21
library/src/hooks/cms_hook_form_alter.e
Normal file
21
library/src/hooks/cms_hook_form_alter.e
Normal file
@@ -0,0 +1,21 @@
|
||||
note
|
||||
description: "[
|
||||
Hook providing a way to alter a form.
|
||||
]"
|
||||
date: "$Date$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_FORM_ALTER
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
feature -- Hook
|
||||
|
||||
form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on form `a_form' and its associated data `a_form_data',
|
||||
-- for related response `a_response'.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
21
library/src/hooks/cms_hook_menu_alter.e
Normal file
21
library/src/hooks/cms_hook_menu_alter.e
Normal file
@@ -0,0 +1,21 @@
|
||||
note
|
||||
description: "[
|
||||
Hook providing a way to alter a menu
|
||||
]"
|
||||
date: "$Date$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_MENU_ALTER
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
feature -- Hook
|
||||
|
||||
menu_alter (a_menu: CMS_MENU; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on menu `a_menu'
|
||||
-- for related response `a_response'.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
21
library/src/hooks/cms_hook_menu_system_alter.e
Normal file
21
library/src/hooks/cms_hook_menu_system_alter.e
Normal file
@@ -0,0 +1,21 @@
|
||||
note
|
||||
description: "[
|
||||
Hook providing a way to alter the CMS menu system.
|
||||
]"
|
||||
date: "$Date$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
feature -- Hook
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on collection of menu contained by `a_menu_system'
|
||||
-- for related response `a_response'.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
30
library/src/hooks/cms_hook_value_table_alter.e
Normal file
30
library/src/hooks/cms_hook_value_table_alter.e
Normal file
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: "[
|
||||
Hook providing a way to alter the value table for a response.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_HOOK_VALUE_TABLE_ALTER
|
||||
|
||||
inherit
|
||||
CMS_HOOK
|
||||
|
||||
feature -- Hook
|
||||
|
||||
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
97
library/src/kernel/cms_common_api.e
Normal file
97
library/src/kernel/cms_common_api.e
Normal file
@@ -0,0 +1,97 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CMS_COMMON_API}."
|
||||
author: ""
|
||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||
revision: "$Revision: 95708 $"
|
||||
|
||||
deferred class
|
||||
CMS_COMMON_API
|
||||
|
||||
inherit
|
||||
WSF_API_UTILITIES
|
||||
|
||||
feature {NONE} -- Access
|
||||
|
||||
site_url: READABLE_STRING_8
|
||||
do
|
||||
Result := ""
|
||||
end
|
||||
|
||||
base_url: detachable READABLE_STRING_8
|
||||
-- Base url if any.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
user_link (u: CMS_USER): like link
|
||||
do
|
||||
Result := link (u.name, "/user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
node_link (n: CMS_NODE): like link
|
||||
do
|
||||
Result := link (n.title, "/node/" + n.id.out, Void)
|
||||
end
|
||||
|
||||
user_url (u: CMS_USER): like url
|
||||
do
|
||||
Result := url ("/user/" + u.id.out, Void)
|
||||
end
|
||||
|
||||
node_url (n: CMS_NODE): like url
|
||||
do
|
||||
Result := url ("/node/" + n.id.out, Void)
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
is_empty (s: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `s' is Void or empty ?
|
||||
do
|
||||
Result := s = Void or else s.is_empty
|
||||
end
|
||||
|
||||
unix_timestamp (dt: DATE_TIME): INTEGER_64
|
||||
do
|
||||
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp (dt)
|
||||
end
|
||||
|
||||
unix_timestamp_to_date_time (t: INTEGER_64): DATE_TIME
|
||||
do
|
||||
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (t)
|
||||
end
|
||||
|
||||
string_unix_timestamp_to_date_time (s: READABLE_STRING_8): DATE_TIME
|
||||
do
|
||||
if s.is_integer_64 then
|
||||
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (s.to_integer_64)
|
||||
else
|
||||
Result := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp_to_date_time (0)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
options_boolean (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING; dft: BOOLEAN): BOOLEAN
|
||||
do
|
||||
if attached {BOOLEAN} opts.item (k) as h then
|
||||
Result := h
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
options_string (opts: HASH_TABLE [detachable ANY, STRING]; k: STRING): detachable STRING
|
||||
do
|
||||
if attached {STRING} opts.item (k) as s then
|
||||
Result := s
|
||||
end
|
||||
end
|
||||
|
||||
-- html_encoder: HTML_ENCODER
|
||||
-- once ("thread")
|
||||
-- create Result
|
||||
-- end
|
||||
|
||||
end
|
||||
28
library/src/kernel/content/cms_block.e
Normal file
28
library/src/kernel/content/cms_block.e
Normal file
@@ -0,0 +1,28 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOCK}."
|
||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||
|
||||
deferred class
|
||||
CMS_BLOCK
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: READABLE_STRING_8
|
||||
deferred
|
||||
end
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- status report
|
||||
|
||||
is_enabled: BOOLEAN
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
to_html (a_theme: CMS_THEME): STRING_8
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
42
library/src/kernel/content/cms_block_region.e
Normal file
42
library/src/kernel/content/cms_block_region.e
Normal file
@@ -0,0 +1,42 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BLOCK_REGION}."
|
||||
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
|
||||
|
||||
class
|
||||
CMS_BLOCK_REGION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_name: like name)
|
||||
do
|
||||
name := a_name
|
||||
create blocks.make (1)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: READABLE_STRING_8
|
||||
|
||||
blocks: ARRAYED_LIST [CMS_BLOCK]
|
||||
|
||||
feature -- Element change
|
||||
|
||||
extend (b: CMS_BLOCK)
|
||||
do
|
||||
blocks.force (b)
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
79
library/src/kernel/content/cms_content_block.e
Normal file
79
library/src/kernel/content/cms_content_block.e
Normal file
@@ -0,0 +1,79 @@
|
||||
note
|
||||
description: "Summary description for {CMS_CONTENT_BLOCK}."
|
||||
author: ""
|
||||
date: "$Date: 2014-10-30 12:55:33 -0300 (ju. 30 de oct. de 2014) $"
|
||||
revision: "$Revision: 96018 $"
|
||||
|
||||
class
|
||||
CMS_CONTENT_BLOCK
|
||||
|
||||
inherit
|
||||
CMS_BLOCK
|
||||
|
||||
create
|
||||
make,
|
||||
make_raw
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
||||
do
|
||||
is_enabled := True
|
||||
name := a_name
|
||||
title := a_title
|
||||
content := a_content
|
||||
format := a_format
|
||||
end
|
||||
|
||||
make_raw (a_name: like name; a_title: like title; a_content: like content; a_format: like format)
|
||||
do
|
||||
make (a_name, a_title, a_content, a_format)
|
||||
set_is_raw (True)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: READABLE_STRING_8
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
|
||||
content: READABLE_STRING_8
|
||||
|
||||
format: detachable CONTENT_FORMAT
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_raw: BOOLEAN
|
||||
-- Is raw?
|
||||
-- If True, do not get wrapped it with block specific div
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_is_raw (b: BOOLEAN)
|
||||
do
|
||||
is_raw := b
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
to_html (a_theme: CMS_THEME): STRING_8
|
||||
do
|
||||
-- Why in this particular case theme is not used to generate the content?
|
||||
|
||||
if attached format as f then
|
||||
Result := f.formatted_output (content)
|
||||
else
|
||||
Result := content
|
||||
end
|
||||
end
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
35
library/src/kernel/content/cms_encoders.e
Normal file
35
library/src/kernel/content/cms_encoders.e
Normal file
@@ -0,0 +1,35 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ENCODERS}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ENCODERS
|
||||
|
||||
feature -- Encoders
|
||||
|
||||
url_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
|
||||
local
|
||||
enc: URL_ENCODER
|
||||
do
|
||||
create enc
|
||||
if s /= Void then
|
||||
Result := enc.general_encoded_string (s)
|
||||
else
|
||||
create Result.make_empty
|
||||
end
|
||||
end
|
||||
|
||||
html_encoded (s: detachable READABLE_STRING_GENERAL): STRING_8
|
||||
local
|
||||
enc: HTML_ENCODER
|
||||
do
|
||||
create enc
|
||||
if s /= Void then
|
||||
Result := enc.general_encoded_string (s)
|
||||
else
|
||||
create Result.make_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
41
library/src/kernel/content/cms_menu_block.e
Normal file
41
library/src/kernel/content/cms_menu_block.e
Normal file
@@ -0,0 +1,41 @@
|
||||
note
|
||||
description: "Summary description for {CMS_MENU_BLOCK}."
|
||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||
|
||||
class
|
||||
CMS_MENU_BLOCK
|
||||
|
||||
inherit
|
||||
CMS_BLOCK
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_menu: like menu)
|
||||
do
|
||||
is_enabled := True
|
||||
menu := a_menu
|
||||
name := a_menu.name
|
||||
title := a_menu.title
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
menu: CMS_MENU
|
||||
|
||||
name: READABLE_STRING_8
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
|
||||
is_horizontal: BOOLEAN
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
to_html (a_theme: CMS_THEME): STRING_8
|
||||
do
|
||||
Result := a_theme.menu_html (menu, is_horizontal)
|
||||
end
|
||||
|
||||
end
|
||||
92
library/src/kernel/content/cms_value_table.e
Normal file
92
library/src/kernel/content/cms_value_table.e
Normal file
@@ -0,0 +1,92 @@
|
||||
note
|
||||
description: "[
|
||||
Object containing a collection of values.
|
||||
It is typically used by `{CMS_RESPONSE}.values' .
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_VALUE_TABLE
|
||||
|
||||
inherit
|
||||
TABLE_ITERABLE [detachable ANY, READABLE_STRING_GENERAL]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (nb: INTEGER)
|
||||
do
|
||||
create table.make (nb)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
count: INTEGER
|
||||
-- Number of items.
|
||||
do
|
||||
Result := table.count
|
||||
end
|
||||
|
||||
item (key: READABLE_STRING_GENERAL): detachable ANY
|
||||
-- Item associated with `key', if present
|
||||
-- otherwise default value of type `G'.
|
||||
note
|
||||
option: stable
|
||||
do
|
||||
Result := table.item (key)
|
||||
end
|
||||
|
||||
has (key: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Has item associated with key `key'?
|
||||
do
|
||||
Result := table.has (key)
|
||||
end
|
||||
|
||||
new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := table.new_cursor
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
put (new: detachable ANY; key: READABLE_STRING_GENERAL)
|
||||
-- Insert `new' with `key' if there is no other item
|
||||
-- associated with the same key.
|
||||
do
|
||||
table.put (new, key)
|
||||
end
|
||||
|
||||
force (new: detachable ANY; key: READABLE_STRING_GENERAL)
|
||||
-- Update table so that `new' will be the item associated
|
||||
-- with `key'.
|
||||
do
|
||||
table.force (new, key)
|
||||
end
|
||||
|
||||
remove (key: READABLE_STRING_GENERAL)
|
||||
do
|
||||
table.remove (key)
|
||||
end
|
||||
|
||||
feature {NONE} -- Duplication
|
||||
|
||||
table: STRING_TABLE [detachable ANY]
|
||||
|
||||
invariant
|
||||
table_set: table /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
64
library/src/kernel/content/format/cms_formats.e
Normal file
64
library/src/kernel/content/format/cms_formats.e
Normal file
@@ -0,0 +1,64 @@
|
||||
note
|
||||
description: "Summary description for {CMS_FORMATS}."
|
||||
author: ""
|
||||
date: "$Date: 2014-10-16 04:45:23 -0300 (ju. 16 de oct. de 2014) $"
|
||||
revision: "$Revision: 95932 $"
|
||||
|
||||
class
|
||||
CMS_FORMATS
|
||||
|
||||
feature -- Access
|
||||
|
||||
format (a_name: like {CONTENT_FORMAT}.name): detachable CONTENT_FORMAT
|
||||
do
|
||||
across
|
||||
all_formats as c
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
if c.item.name.same_string (a_name) then
|
||||
Result := c.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
all_formats: LIST [CONTENT_FORMAT]
|
||||
once
|
||||
create {ARRAYED_LIST [CONTENT_FORMAT]} Result.make (3)
|
||||
Result.force (plain_text)
|
||||
Result.force (full_html)
|
||||
Result.force (filtered_html)
|
||||
end
|
||||
|
||||
default_format: CONTENT_FORMAT
|
||||
do
|
||||
Result := plain_text --FIXME
|
||||
end
|
||||
|
||||
plain_text: PLAIN_TEXT_CONTENT_FORMAT
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
full_html: FULL_HTML_CONTENT_FORMAT
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
filtered_html: FILTERED_HTML_CONTENT_FORMAT
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
42
library/src/kernel/form/cms_form.e
Normal file
42
library/src/kernel/form/cms_form.e
Normal file
@@ -0,0 +1,42 @@
|
||||
note
|
||||
description: "Summary description for {CMS_FORM}."
|
||||
date: "$Date: 2014-08-28 08:21:49 -0300 (ju. 28 de ago. de 2014) $"
|
||||
revision: "$Revision: 95708 $"
|
||||
|
||||
class
|
||||
CMS_FORM
|
||||
|
||||
inherit
|
||||
WSF_FORM
|
||||
rename
|
||||
process as process_form
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
prepare (a_response: CMS_RESPONSE)
|
||||
do
|
||||
a_response.invoke_form_alter (Current, Void)
|
||||
end
|
||||
|
||||
process (a_response: CMS_RESPONSE)
|
||||
do
|
||||
process_form (a_response.request, agent on_prepared (a_response, ?), agent on_processed (a_response, ?))
|
||||
end
|
||||
|
||||
on_prepared (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
|
||||
do
|
||||
a_response.invoke_form_alter (Current, fd)
|
||||
end
|
||||
|
||||
on_processed (a_response: CMS_RESPONSE; fd: WSF_FORM_DATA)
|
||||
do
|
||||
if not fd.is_valid or fd.has_error then
|
||||
a_response.report_form_errors (fd)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
104
library/src/kernel/link/cms_menu_system.e
Normal file
104
library/src/kernel/link/cms_menu_system.e
Normal file
@@ -0,0 +1,104 @@
|
||||
note
|
||||
description: "[
|
||||
Menu associated with CMS system.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_MENU_SYSTEM
|
||||
|
||||
inherit
|
||||
ITERABLE [CMS_MENU]
|
||||
|
||||
REFACTORING_HELPER
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create a predefined manu system
|
||||
do
|
||||
to_implement ("Refactor, take the info from a Database or Configuration file.")
|
||||
create items.make (5)
|
||||
force (create {CMS_MENU}.make ("primary", 3))
|
||||
force (create {CMS_MENU}.make_with_title ("management", "Management", 3))
|
||||
force (create {CMS_MENU}.make_with_title ("secondary", "Navigation", 3))
|
||||
force (create {CMS_MENU}.make_with_title ("user", "User", 3))
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
item (n: like {CMS_MENU}.name): CMS_MENU
|
||||
-- Menu associated with name `n',
|
||||
-- if none, it is created.
|
||||
local
|
||||
m: detachable CMS_MENU
|
||||
do
|
||||
m := items.item (n)
|
||||
if m = Void then
|
||||
create m.make (n, 3)
|
||||
force (m)
|
||||
end
|
||||
Result := m
|
||||
end
|
||||
|
||||
main_menu: CMS_MENU
|
||||
obsolete
|
||||
"Use `primary_menu' [Nov/2014]"
|
||||
do
|
||||
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")
|
||||
end
|
||||
|
||||
navigation_menu: CMS_MENU
|
||||
do
|
||||
Result := item ("navigation")
|
||||
end
|
||||
|
||||
user_menu: CMS_MENU
|
||||
do
|
||||
Result := item ("user")
|
||||
end
|
||||
|
||||
primary_tabs: CMS_MENU
|
||||
do
|
||||
Result := item ("primary-tabs")
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
force (m: CMS_MENU)
|
||||
-- Add menu `m'.
|
||||
do
|
||||
items.force (m, m.name)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_cursor: ITERATION_CURSOR [CMS_MENU]
|
||||
-- Fresh cursor associated with current structure.
|
||||
do
|
||||
Result := items.new_cursor
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
items: STRING_TABLE [CMS_MENU]
|
||||
|
||||
end
|
||||
73
library/src/modules/basic_auth/basic_auth_module.e
Normal file
73
library/src/modules/basic_auth/basic_auth_module.e
Normal file
@@ -0,0 +1,73 @@
|
||||
note
|
||||
description: "This module allows the use of HTTP Basic Authentication to restrict access by looking up users in the given providers."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASIC_AUTH_MODULE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_MODULE
|
||||
redefine
|
||||
filters
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
name := "basic auth"
|
||||
version := "1.0"
|
||||
description := "Service to manage basic authentication"
|
||||
package := "core"
|
||||
end
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
router (a_api: CMS_API): WSF_ROUTER
|
||||
-- Node router.
|
||||
do
|
||||
create Result.make (2)
|
||||
configure_api_login (a_api, Result)
|
||||
configure_api_logoff (a_api, Result)
|
||||
end
|
||||
|
||||
feature -- Access: 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 (a_api))
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: routes
|
||||
|
||||
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 (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 (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 (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
a_router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods)
|
||||
end
|
||||
|
||||
end
|
||||
57
library/src/modules/basic_auth/filter/basic_auth_filter.e
Normal file
57
library/src/modules/basic_auth/filter/basic_auth_filter.e
Normal file
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description: "Processes a HTTP request's BASIC authorization headers, putting the result into the execution variable user."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASIC_AUTH_FILTER
|
||||
|
||||
inherit
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
CMS_HANDLER
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
local
|
||||
l_auth: HTTP_AUTHORIZATION
|
||||
do
|
||||
log.write_debug (generator + ".execute " )
|
||||
create l_auth.make (req.http_authorization)
|
||||
if attached req.raw_header_data as l_raw_data then
|
||||
log.write_debug (generator + ".execute " + l_raw_data )
|
||||
end
|
||||
-- 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.is_valid_credential (l_auth_login, l_auth_password) then
|
||||
if attached api.user_by_name (l_auth_login) as l_user then
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Maybe we need to store in the credentials in a shared context SECURITY_CONTEXT")
|
||||
-- req.set_execution_variable ("security_content", create SECURITY_CONTEXT.make (l_user))
|
||||
-- other authentication filters (OpenID, etc) should implement the same approach.
|
||||
end
|
||||
req.set_execution_variable ("user", l_user)
|
||||
execute_next (req, res)
|
||||
else
|
||||
debug ("refactor_fixme")
|
||||
to_implement ("Internal server error")
|
||||
end
|
||||
end
|
||||
else
|
||||
log.write_error (generator + ".execute login_valid failed for: " + l_auth_login )
|
||||
execute_next (req, res)
|
||||
end
|
||||
else
|
||||
log.write_error (generator + ".execute Not valid")
|
||||
execute_next (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
28
library/src/modules/basic_auth/filter/cors_filter.e
Normal file
28
library/src/modules/basic_auth/filter/cors_filter.e
Normal file
@@ -0,0 +1,28 @@
|
||||
note
|
||||
description: "CORS filter"
|
||||
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
|
||||
revision: "$Revision: 95593 $"
|
||||
|
||||
class
|
||||
CORS_FILTER
|
||||
|
||||
inherit
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
local
|
||||
l_header: HTTP_HEADER
|
||||
do
|
||||
create l_header.make
|
||||
-- l_header.add_header_key_value ("Access-Control-Allow-Origin", "localhost")
|
||||
l_header.add_header_key_value ("Access-Control-Allow-Headers", "*")
|
||||
l_header.add_header_key_value ("Access-Control-Allow-Methods", "*")
|
||||
l_header.add_header_key_value ("Access-Control-Allow-Credentials", "true")
|
||||
res.put_header_lines (l_header)
|
||||
execute_next (req, res)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "Summary description for {BASIC_AUTH_LOGIN_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASIC_AUTH_LOGIN_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler.
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler.
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
log.write_information(generator + ".do_get Processing basic auth login")
|
||||
if attached {STRING_32} current_user_name (req) as l_user then
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url("/"))
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_authenticate (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
note
|
||||
description: "Summary description for {BASIC_AUTH_LOGOFF_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASIC_AUTH_LOGOFF_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler.
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler.
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
log.write_information(generator + ".do_get Processing basic auth logoff")
|
||||
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, api)
|
||||
l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
l_page.execute
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
85
library/src/modules/cms_module.e
Normal file
85
library/src/modules/cms_module.e
Normal file
@@ -0,0 +1,85 @@
|
||||
note
|
||||
description: "Describe module features that adds one or more features to your web site."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_MODULE
|
||||
|
||||
inherit
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature -- Access
|
||||
|
||||
is_enabled: BOOLEAN
|
||||
-- Is the module enabled?
|
||||
|
||||
name: STRING
|
||||
-- Name of the module.
|
||||
|
||||
description: STRING
|
||||
-- Description of the module.
|
||||
|
||||
package: STRING
|
||||
--
|
||||
|
||||
version: STRING
|
||||
-- Version od the module?
|
||||
|
||||
feature -- 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)
|
||||
-- Module hooks configuration.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Filter
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Optional list of filter for Current module.
|
||||
require
|
||||
is_enabled: is_enabled
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
enable
|
||||
-- enable the module.
|
||||
do
|
||||
is_enabled := True
|
||||
ensure
|
||||
module_enabled: is_enabled
|
||||
end
|
||||
|
||||
disable
|
||||
-- disable the module.
|
||||
do
|
||||
is_enabled := False
|
||||
ensure
|
||||
module_disbaled: not is_enabled
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
help_text (a_path: STRING): STRING
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
to_implement ("Add the corresponing implementation.")
|
||||
end
|
||||
create Result.make_empty
|
||||
end
|
||||
|
||||
end
|
||||
64
library/src/modules/cms_module_collection.e
Normal file
64
library/src/modules/cms_module_collection.e
Normal file
@@ -0,0 +1,64 @@
|
||||
note
|
||||
description: "Summary description for {CMS_MODULE_COLLECTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_MODULE_COLLECTION
|
||||
|
||||
inherit
|
||||
ITERABLE [CMS_MODULE]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (nb: INTEGER)
|
||||
do
|
||||
create modules.make (nb)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_cursor: INDEXABLE_ITERATION_CURSOR [CMS_MODULE]
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := modules.new_cursor
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has (a_module: CMS_MODULE): BOOLEAN
|
||||
-- Has `a_module'?
|
||||
do
|
||||
Result := modules.has (a_module)
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
-- Number of modules.
|
||||
do
|
||||
Result := modules.count
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
extend (a_module: CMS_MODULE)
|
||||
-- Add module
|
||||
do
|
||||
modules.force (a_module)
|
||||
end
|
||||
|
||||
remove (a_module: CMS_MODULE)
|
||||
-- Remove module
|
||||
do
|
||||
modules.prune_all (a_module)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
modules: ARRAYED_LIST [CMS_MODULE]
|
||||
-- List of available modules.
|
||||
|
||||
end
|
||||
171
library/src/modules/node/handler/node_content_handler.e
Normal file
171
library/src/modules/node/handler/node_content_handler.e
Normal file
@@ -0,0 +1,171 @@
|
||||
note
|
||||
description: "Summary description for {NEW_CONTENT_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_CONTENT_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
rename
|
||||
execute as uri_template_execute,
|
||||
new_mapping as new_uri_template_mapping
|
||||
select
|
||||
new_uri_template_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get,
|
||||
do_post,
|
||||
do_put
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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.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
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
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.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, api)).execute
|
||||
end
|
||||
end
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
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.node (l_id.integer_value) as l_node then
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.integer_value)
|
||||
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, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING}req.form_parameter ("content") as l_content then
|
||||
Result.set_content (l_content.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
217
library/src/modules/node/handler/node_handler.e
Normal file
217
library/src/modules/node/handler/node_handler.e
Normal file
@@ -0,0 +1,217 @@
|
||||
note
|
||||
description: "Summary description for {NODE_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
rename
|
||||
execute as uri_template_execute,
|
||||
new_mapping as new_uri_template_mapping
|
||||
select
|
||||
new_uri_template_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get,
|
||||
do_post,
|
||||
do_put,
|
||||
do_delete
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
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.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
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
-- Factory
|
||||
new_node (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
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.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, api)).execute
|
||||
end
|
||||
end
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
-- New node
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_author (l_user)
|
||||
api.new_node (u_node)
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url (""))
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
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.node (l_id.integer_value) as l_node then
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.integer_value)
|
||||
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, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
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.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, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
feature {NONE} -- Node
|
||||
|
||||
new_node (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
if attached current_user_name (req) then
|
||||
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
|
||||
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
||||
Result.set_title (l_title.value)
|
||||
end
|
||||
if attached {WSF_STRING} req.form_parameter ("summary") as l_summary then
|
||||
Result.set_summary (l_summary.value)
|
||||
end
|
||||
if attached {WSF_STRING} req.form_parameter ("content") as l_content then
|
||||
Result.set_content (l_content.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
171
library/src/modules/node/handler/node_summary_handler.e
Normal file
171
library/src/modules/node/handler/node_summary_handler.e
Normal file
@@ -0,0 +1,171 @@
|
||||
note
|
||||
description: "Summary description for {NODE_SUMMARY_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_SUMMARY_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
rename
|
||||
execute as uri_template_execute,
|
||||
new_mapping as new_uri_template_mapping
|
||||
select
|
||||
new_uri_template_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get,
|
||||
do_post,
|
||||
do_put
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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.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
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
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.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, api)).execute
|
||||
end
|
||||
end
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
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.node (l_id.integer_value) as l_node then
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.integer_value)
|
||||
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, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING}req.form_parameter ("summary") as l_summary then
|
||||
Result.set_summary (l_summary.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
169
library/src/modules/node/handler/node_title_handler.e
Normal file
169
library/src/modules/node/handler/node_title_handler.e
Normal file
@@ -0,0 +1,169 @@
|
||||
note
|
||||
description: "Summary description for {NODE_TITLE_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_TITLE_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
rename
|
||||
execute as uri_template_execute,
|
||||
new_mapping as new_uri_template_mapping
|
||||
select
|
||||
new_uri_template_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get,
|
||||
do_post,
|
||||
do_put
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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.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
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
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.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, api)).execute
|
||||
end
|
||||
end
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {ERROR_500_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
u_node: CMS_NODE
|
||||
do
|
||||
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.node (l_id.integer_value) as l_node then
|
||||
u_node := extract_data_form (req)
|
||||
u_node.set_id (l_id.integer_value)
|
||||
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, api)).execute
|
||||
end
|
||||
else
|
||||
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
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
|
||||
l_page.add_variable ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.add_variable ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
|
||||
feature -- {NONE} Form data
|
||||
|
||||
extract_data_form (req: WSF_REQUEST): CMS_NODE
|
||||
-- Extract request form data and build a object
|
||||
-- Node
|
||||
do
|
||||
create Result.make ("", "", "")
|
||||
if attached {WSF_STRING} req.form_parameter ("title") as l_title then
|
||||
Result.set_title (l_title.value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
59
library/src/modules/node/handler/nodes_handler.e
Normal file
59
library/src/modules/node/handler/nodes_handler.e
Normal file
@@ -0,0 +1,59 @@
|
||||
note
|
||||
description: "Summary description for {NODES_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODES_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
-- 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, api)
|
||||
l_page.add_variable (api.nodes, "nodes")
|
||||
l_page.execute
|
||||
end
|
||||
end
|
||||
169
library/src/modules/node/node_module.e
Normal file
169
library/src/modules/node/node_module.e
Normal file
@@ -0,0 +1,169 @@
|
||||
note
|
||||
description: "CMS module that bring support for NODE management."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_MODULE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_MODULE
|
||||
redefine
|
||||
register_hooks
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
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_setup
|
||||
end
|
||||
|
||||
|
||||
config: CMS_SETUP
|
||||
-- Node configuration.
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
router (a_api: CMS_API): WSF_ROUTER
|
||||
-- Node router.
|
||||
do
|
||||
create Result.make (5)
|
||||
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 (api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_node_handler: NODE_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
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 (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
l_methods.enable_post
|
||||
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)
|
||||
local
|
||||
l_nodes_handler: NODES_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
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 (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 (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
l_methods.enable_post
|
||||
l_methods.enable_put
|
||||
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
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_report_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/{id}/title", l_report_handler, l_methods)
|
||||
end
|
||||
|
||||
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 (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
l_methods.enable_post
|
||||
l_methods.enable_put
|
||||
a_router.handle_with_request_methods ("/node/{id}/content", l_report_handler, l_methods)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
do
|
||||
a_response.subscribe_to_menu_system_alter_hook (Current)
|
||||
a_response.subscribe_to_block_hook (Current)
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
do
|
||||
Result := <<"node-info">>
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
local
|
||||
-- b: CMS_CONTENT_BLOCK
|
||||
do
|
||||
-- create b.make (a_block_id, "Block::node", "This is a block test", Void)
|
||||
-- a_response.add_block (b, "sidebar_second")
|
||||
end
|
||||
|
||||
menu_system_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 ("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
|
||||
199
library/src/service/cms_api.e
Normal file
199
library/src/service/cms_api.e
Normal file
@@ -0,0 +1,199 @@
|
||||
note
|
||||
description: "API for a CMS"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_API
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_ERROR
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Initialize
|
||||
|
||||
make (a_setup: CMS_SETUP)
|
||||
-- Create the API service with a setup `a_setup'
|
||||
do
|
||||
setup := a_setup
|
||||
create error_handler.make
|
||||
initialize
|
||||
set_successful
|
||||
ensure
|
||||
setup_set: setup = a_setup
|
||||
error_handler_set: not error_handler.has_error
|
||||
end
|
||||
|
||||
setup: CMS_SETUP
|
||||
-- CMS setup.
|
||||
|
||||
initialize
|
||||
-- Initialize the persitent layer.
|
||||
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 (a_auth_login, a_auth_password: READABLE_STRING_32): BOOLEAN
|
||||
-- Is the credentials `a_auth_login' and `a_auth_password' valid?
|
||||
do
|
||||
Result := storage.is_valid_credential (a_auth_login, a_auth_password)
|
||||
end
|
||||
|
||||
feature -- Access: Node
|
||||
|
||||
nodes: LIST[CMS_NODE]
|
||||
-- List of nodes.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Implementation")
|
||||
end
|
||||
Result := storage.recent_nodes (0, 10)
|
||||
end
|
||||
|
||||
recent_nodes (a_offset, a_rows: INTEGER): LIST[CMS_NODE]
|
||||
-- List of the `a_rows' most recent nodes starting from `a_offset'.
|
||||
do
|
||||
Result := storage.recent_nodes (a_offset, a_rows)
|
||||
end
|
||||
|
||||
node (a_id: INTEGER_64): detachable CMS_NODE
|
||||
-- Node by ID.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Check preconditions")
|
||||
end
|
||||
Result := storage.node (a_id)
|
||||
end
|
||||
|
||||
feature -- Change: Node
|
||||
|
||||
new_node (a_node: CMS_NODE)
|
||||
-- Add a new node `a_node'
|
||||
do
|
||||
storage.save_node (a_node)
|
||||
end
|
||||
|
||||
delete_node (a_id: INTEGER_64)
|
||||
-- Delete a node identified by `a_id', if any.
|
||||
do
|
||||
storage.delete_node (a_id)
|
||||
end
|
||||
|
||||
update_node (a_id: like {CMS_USER}.id; a_node: CMS_NODE)
|
||||
-- Update node by id `a_id' with `a_node' data.
|
||||
do
|
||||
storage.update_node (a_id,a_node)
|
||||
end
|
||||
|
||||
update_node_title (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_title: READABLE_STRING_32)
|
||||
-- Update node title, with user identified by `a_id', with node id `a_node_id' and a new title `a_title'.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Check preconditions")
|
||||
end
|
||||
storage.update_node_title (a_id,a_node_id,a_title)
|
||||
end
|
||||
|
||||
update_node_summary (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_summary: READABLE_STRING_32)
|
||||
-- Update node summary, with user identified by `a_id', with node id `a_node_id' and a new summary `a_summary'.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Check preconditions")
|
||||
end
|
||||
storage.update_node_summary (a_id,a_node_id, a_summary)
|
||||
end
|
||||
|
||||
update_node_content (a_id: like {CMS_USER}.id; a_node_id: like {CMS_NODE}.id; a_content: READABLE_STRING_32)
|
||||
-- Update node content, with user identified by `a_id', with node id `a_node_id' and a new content `a_content'.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Check preconditions")
|
||||
end
|
||||
storage.update_node_content (a_id,a_node_id, a_content)
|
||||
end
|
||||
|
||||
|
||||
feature -- Access: User
|
||||
|
||||
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
|
||||
-- User by name `a_user_name', if any.
|
||||
do
|
||||
Result := storage.user_by_name (a_username)
|
||||
end
|
||||
|
||||
feature -- Change User
|
||||
|
||||
new_user (a_user: CMS_USER)
|
||||
-- Add a new user `a_user'.
|
||||
do
|
||||
if
|
||||
attached a_user.password as l_password and then
|
||||
attached a_user.email as l_email
|
||||
then
|
||||
storage.save_user (a_user)
|
||||
else
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Add error")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Implemenataion
|
||||
|
||||
|
||||
storage: CMS_STORAGE
|
||||
-- Persistence storage.
|
||||
|
||||
end
|
||||
|
||||
17
library/src/service/cms_api_options.e
Normal file
17
library/src/service/cms_api_options.e
Normal file
@@ -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
|
||||
58
library/src/service/cms_request_util.e
Normal file
58
library/src/service/cms_request_util.e
Normal file
@@ -0,0 +1,58 @@
|
||||
note
|
||||
description: "Summary description for {CMS_REQUEST_UTIL}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_REQUEST_UTIL
|
||||
|
||||
inherit
|
||||
|
||||
CMS_ENCODERS
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature -- User
|
||||
|
||||
current_user_name (req: WSF_REQUEST): detachable READABLE_STRING_32
|
||||
-- Current user name or Void in case of Guest users.
|
||||
note
|
||||
EIS: "src=eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
|
||||
do
|
||||
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
|
||||
-- Current user or Void in case of Guest user.
|
||||
note
|
||||
EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute"
|
||||
do
|
||||
if attached {CMS_USER} req.execution_variable ("user") as l_user then
|
||||
Result := l_user
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Media Type
|
||||
|
||||
current_media_type (req: WSF_REQUEST): detachable READABLE_STRING_32
|
||||
-- Current media type or Void if it's not acceptable.
|
||||
do
|
||||
if attached {STRING} req.execution_variable ("media_type") as l_type then
|
||||
Result := l_type
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Absolute Host
|
||||
|
||||
absolute_host (req: WSF_REQUEST; a_path:STRING): STRING
|
||||
do
|
||||
Result := req.absolute_script_url (a_path)
|
||||
if Result.last_index_of ('/', Result.count) = Result.count then
|
||||
Result.remove_tail (1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
261
library/src/service/cms_service.e
Normal file
261
library/src/service/cms_service.e
Normal file
@@ -0,0 +1,261 @@
|
||||
note
|
||||
description: "[
|
||||
This class implements the CMS service
|
||||
|
||||
It could be used to implement the main EWF service, or
|
||||
even for a specific handler.
|
||||
]"
|
||||
|
||||
class
|
||||
CMS_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_ROUTED_SKELETON_SERVICE
|
||||
rename
|
||||
execute as execute_service
|
||||
undefine
|
||||
requires_proxy
|
||||
redefine
|
||||
execute_default
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
WSF_FILTER
|
||||
rename
|
||||
execute as execute_filter
|
||||
end
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
WSF_URI_HELPER_FOR_ROUTED_SERVICE
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_api: CMS_API)
|
||||
-- Build a CMS service with `a_api'
|
||||
do
|
||||
api := a_api
|
||||
configuration := a_api.setup.configuration
|
||||
initialize
|
||||
ensure
|
||||
api_set: api = a_api
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize various parts of the CMS service.
|
||||
do
|
||||
initialize_modules
|
||||
initialize_users
|
||||
initialize_auth_engine
|
||||
initialize_mailer
|
||||
initialize_router
|
||||
initialize_filter
|
||||
end
|
||||
|
||||
initialize_modules
|
||||
-- Intialize modules and keep only enabled modules.
|
||||
local
|
||||
l_module: CMS_MODULE
|
||||
l_available_modules: CMS_MODULE_COLLECTION
|
||||
do
|
||||
log.write_debug (generator + ".initialize_modules")
|
||||
l_available_modules := setup.modules
|
||||
create modules.make (l_available_modules.count)
|
||||
across
|
||||
l_available_modules as ic
|
||||
loop
|
||||
l_module := ic.item
|
||||
if l_module.is_enabled then
|
||||
modules.extend (l_module)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
only_enabled_modules: across modules as ic all ic.item.is_enabled end
|
||||
end
|
||||
|
||||
initialize_users
|
||||
-- Initialize users.
|
||||
do
|
||||
end
|
||||
|
||||
initialize_mailer
|
||||
-- Initialize mailer engine.
|
||||
do
|
||||
to_implement ("To Implement mailer")
|
||||
end
|
||||
|
||||
initialize_auth_engine
|
||||
do
|
||||
to_implement ("To Implement authentication engine")
|
||||
end
|
||||
|
||||
feature -- Settings: router
|
||||
|
||||
setup_router
|
||||
-- <Precursor>
|
||||
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.
|
||||
|
||||
l_router := router
|
||||
configure_api_root (l_router)
|
||||
|
||||
-- Include routes from modules.
|
||||
l_api := api
|
||||
across
|
||||
modules as ic
|
||||
loop
|
||||
l_module := ic.item
|
||||
l_router.import (l_module.router (l_api))
|
||||
end
|
||||
-- Configure files handler.
|
||||
configure_api_file_handler (l_router)
|
||||
end
|
||||
|
||||
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 (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
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 (a_router: WSF_ROUTER)
|
||||
local
|
||||
fhdl: WSF_FILE_SYSTEM_HANDLER
|
||||
do
|
||||
log.write_debug (generator + ".configure_api_file_handler")
|
||||
create fhdl.make_hidden_with_path (setup.layout.www_path)
|
||||
fhdl.disable_index
|
||||
fhdl.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_with_request_methods ("/", fhdl, router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Execute Filter
|
||||
|
||||
execute_filter (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
do
|
||||
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
|
||||
execute_service (req, res)
|
||||
end
|
||||
|
||||
feature -- Filters
|
||||
|
||||
create_filter
|
||||
-- Create `filter'.
|
||||
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
|
||||
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
-- Error Filter
|
||||
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 (l_api) as l_m_filters
|
||||
then
|
||||
across l_m_filters as f_ic loop
|
||||
f := f_ic.item
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
filter := l_filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'.
|
||||
local
|
||||
f: WSF_FILTER
|
||||
do
|
||||
log.write_debug (generator + ".setup_filter")
|
||||
|
||||
from
|
||||
f := filter
|
||||
until
|
||||
not attached f.next as l_next
|
||||
loop
|
||||
f := l_next
|
||||
end
|
||||
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.
|
||||
--| Maybe we can compute it (using `setup') instead of using memory.
|
||||
|
||||
modules: CMS_MODULE_COLLECTION
|
||||
-- Configurator of possible modules.
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Default request handler if no other are relevant
|
||||
do
|
||||
to_implement ("Default response for CMS_SERVICE")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
129
library/src/service/cms_url_utilities.e
Normal file
129
library/src/service/cms_url_utilities.e
Normal file
@@ -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
|
||||
33
library/src/service/filter/cms_error_filter.e
Normal file
33
library/src/service/filter/cms_error_filter.e
Normal file
@@ -0,0 +1,33 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ERROR_FILTER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ERROR_FILTER
|
||||
|
||||
inherit
|
||||
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
CMS_HANDLER
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter
|
||||
do
|
||||
if not api.error_handler.has_error then
|
||||
log.write_information (generator + ".execute")
|
||||
execute_next (req, res)
|
||||
else
|
||||
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
|
||||
|
||||
end
|
||||
38
library/src/service/handler/cms_handler.e
Normal file
38
library/src/service/handler/cms_handler.e
Normal file
@@ -0,0 +1,38 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
WSF_HANDLER
|
||||
|
||||
CMS_REQUEST_UTIL
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_api: CMS_API)
|
||||
do
|
||||
api := a_api
|
||||
end
|
||||
|
||||
feature -- Setup
|
||||
|
||||
setup: CMS_SETUP
|
||||
do
|
||||
Result := api.setup
|
||||
end
|
||||
|
||||
feature -- API Service
|
||||
|
||||
api: CMS_API
|
||||
|
||||
end
|
||||
54
library/src/service/handler/cms_root_handler.e
Normal file
54
library/src/service/handler/cms_root_handler.e
Normal file
@@ -0,0 +1,54 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ROOT_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ROOT_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
rename
|
||||
execute as uri_execute,
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- execute
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
do
|
||||
execute_methods (req, res)
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
(create {HOME_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
|
||||
end
|
||||
61
library/src/service/response/cms_generic_response.e
Normal file
61
library/src/service/response/cms_generic_response.e
Normal file
@@ -0,0 +1,61 @@
|
||||
note
|
||||
description: "Summary description for {CMS_GENERIC_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_GENERIC_RESPONSE
|
||||
|
||||
feature -- Responses
|
||||
|
||||
new_response_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
|
||||
-- Redirect to `a_location'
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_html
|
||||
h.put_current_date
|
||||
h.put_location (a_location)
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.see_other)
|
||||
res.put_header_text (h.string)
|
||||
end
|
||||
|
||||
new_response_authenticate (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Handle authenticate.
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_html
|
||||
h.put_current_date
|
||||
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMSRoc-User%"")
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
res.put_header_text (h.string)
|
||||
end
|
||||
|
||||
new_response_denied (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Handle access denied.
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_html
|
||||
h.put_current_date
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
res.put_header_text (h.string)
|
||||
end
|
||||
|
||||
new_response_unauthorized (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Handle not authorized.
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_html
|
||||
h.put_current_date
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
|
||||
res.put_header_text (h.string)
|
||||
end
|
||||
|
||||
end
|
||||
983
library/src/service/response/cms_response.e
Normal file
983
library/src/service/response/cms_response.e
Normal file
@@ -0,0 +1,983 @@
|
||||
note
|
||||
description: "Generic CMS Response.It builds the content to get process to render the output"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_URL_UTILITIES
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
|
||||
do
|
||||
status_code := {HTTP_STATUS_CODE}.ok
|
||||
api := a_api
|
||||
request := req
|
||||
response := res
|
||||
create header.make
|
||||
create values.make (3)
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
get_theme
|
||||
create menu_system.make
|
||||
initialize_block_region_settings
|
||||
create hook_subscribers.make (0)
|
||||
register_hooks
|
||||
end
|
||||
|
||||
register_hooks
|
||||
local
|
||||
l_module: CMS_MODULE
|
||||
l_available_modules: CMS_MODULE_COLLECTION
|
||||
do
|
||||
l_available_modules := setup.modules
|
||||
across
|
||||
l_available_modules as ic
|
||||
loop
|
||||
l_module := ic.item
|
||||
if l_module.is_enabled then
|
||||
if attached {CMS_HOOK_AUTO_REGISTER} l_module as l_auto then
|
||||
l_auto.auto_subscribe_to_hooks (Current)
|
||||
end
|
||||
l_module.register_hooks (Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
request: WSF_REQUEST
|
||||
|
||||
response: WSF_RESPONSE
|
||||
|
||||
api: CMS_API
|
||||
-- Current CMS API.
|
||||
|
||||
setup: CMS_SETUP
|
||||
-- Current setup
|
||||
do
|
||||
Result := api.setup
|
||||
end
|
||||
|
||||
status_code: INTEGER
|
||||
|
||||
header: WSF_HEADER
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
|
||||
page_title: detachable READABLE_STRING_32
|
||||
-- Page title
|
||||
|
||||
main_content: detachable STRING_8
|
||||
|
||||
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
|
||||
do
|
||||
Result := setup.site_name
|
||||
end
|
||||
|
||||
front_page_url: READABLE_STRING_8
|
||||
do
|
||||
Result := request.absolute_script_url ("/")
|
||||
end
|
||||
|
||||
values: CMS_VALUE_TABLE
|
||||
-- Associated values indexed by string name.
|
||||
|
||||
|
||||
|
||||
feature -- Permission
|
||||
-- FIXME: to be implemented has_permissions and has_permission.
|
||||
|
||||
feature -- Status
|
||||
-- FIXME: to be implemented
|
||||
-- is_from, is_module, has_js.
|
||||
|
||||
|
||||
feature -- Head customization
|
||||
|
||||
add_additional_head_line (s: READABLE_STRING_8; a_allow_duplication: BOOLEAN)
|
||||
local
|
||||
lst: like additional_page_head_lines
|
||||
do
|
||||
lst := additional_page_head_lines
|
||||
if lst = Void then
|
||||
create {ARRAYED_LIST [like additional_page_head_lines.item]} lst.make (1)
|
||||
additional_page_head_lines := lst
|
||||
end
|
||||
if a_allow_duplication or else across lst as c all not c.item.same_string (s) end then
|
||||
lst.extend (s)
|
||||
end
|
||||
end
|
||||
|
||||
add_style (a_href: STRING; a_media: detachable STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<link rel=%"stylesheet%" href=%""+ a_href + "%" type=%"text/css%""
|
||||
if a_media /= Void then
|
||||
s.append (" media=%""+ a_media + "%"")
|
||||
end
|
||||
s.append ("/>")
|
||||
add_additional_head_line (s, False)
|
||||
end
|
||||
|
||||
add_javascript_url (a_src: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<script type=%"text/javascript%" src=%"" + a_src + "%"></script>"
|
||||
add_additional_head_line (s, False)
|
||||
end
|
||||
|
||||
add_javascript_content (a_script: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<script type=%"text/javascript%">%N" + a_script + "%N</script>"
|
||||
add_additional_head_line (s, True)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_title (t: like title)
|
||||
do
|
||||
title := t
|
||||
set_page_title (t)
|
||||
end
|
||||
|
||||
set_page_title (t: like page_title)
|
||||
do
|
||||
page_title := t
|
||||
end
|
||||
|
||||
set_main_content (s: like main_content)
|
||||
do
|
||||
main_content := s
|
||||
end
|
||||
|
||||
set_value (v: detachable ANY; k: READABLE_STRING_GENERAL)
|
||||
-- Set value `v' associated with name `k'.
|
||||
do
|
||||
values.force (v, k)
|
||||
end
|
||||
|
||||
unset_value (k: READABLE_STRING_GENERAL)
|
||||
-- Unset value associated with name `k'.
|
||||
do
|
||||
values.remove (k)
|
||||
end
|
||||
|
||||
|
||||
feature -- Logging
|
||||
|
||||
log (a_category: READABLE_STRING_8; a_message: READABLE_STRING_8; a_level: INTEGER; a_link: detachable CMS_LINK)
|
||||
local
|
||||
-- l_log: CMS_LOG
|
||||
do
|
||||
debug
|
||||
to_implement ("Add implemenatation")
|
||||
end
|
||||
-- create l_log.make (a_category, a_message, a_level, Void)
|
||||
-- if a_link /= Void then
|
||||
-- l_log.set_link (a_link)
|
||||
-- end
|
||||
-- l_log.set_info (request.http_user_agent)
|
||||
-- service.storage.save_log (l_log)
|
||||
end
|
||||
|
||||
feature -- Formats
|
||||
|
||||
formats: CMS_FORMATS
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
feature -- Menu
|
||||
|
||||
menu_system: CMS_MENU_SYSTEM
|
||||
|
||||
main_menu: CMS_MENU
|
||||
obsolete
|
||||
"Use `primary_menu' [Nov/2014]"
|
||||
do
|
||||
Result := primary_menu
|
||||
end
|
||||
|
||||
primary_menu: CMS_MENU
|
||||
do
|
||||
Result := menu_system.primary_menu
|
||||
end
|
||||
|
||||
management_menu: CMS_MENU
|
||||
do
|
||||
Result := menu_system.management_menu
|
||||
end
|
||||
|
||||
navigation_menu: CMS_MENU
|
||||
do
|
||||
Result := menu_system.navigation_menu
|
||||
end
|
||||
|
||||
user_menu: CMS_MENU
|
||||
do
|
||||
Result := menu_system.user_menu
|
||||
end
|
||||
|
||||
primary_tabs: CMS_MENU
|
||||
do
|
||||
Result := menu_system.primary_tabs
|
||||
end
|
||||
|
||||
feature -- Blocks initialization
|
||||
|
||||
initialize_block_region_settings
|
||||
local
|
||||
l_table: like block_region_settings
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("CHECK:Can we use the same structure as in theme.info?")
|
||||
fixme ("let the user choose ...")
|
||||
end
|
||||
create regions.make_caseless (5)
|
||||
|
||||
create l_table.make_caseless (10)
|
||||
l_table["top"] := "top"
|
||||
l_table["header"] := "header"
|
||||
l_table["highlighted"] := "highlighted"
|
||||
l_table["help"] := "help"
|
||||
l_table["content"] := "content"
|
||||
l_table["footer"] := "footer"
|
||||
l_table["management"] := "first_sidebar"
|
||||
l_table["navigation"] := "first_sidebar"
|
||||
l_table["user"] := "first_sidebar"
|
||||
l_table["bottom"] := "page_bottom"
|
||||
block_region_settings := l_table
|
||||
end
|
||||
|
||||
feature -- Blocks regions
|
||||
|
||||
regions: STRING_TABLE [CMS_BLOCK_REGION]
|
||||
-- Layout regions, that contains blocks.
|
||||
|
||||
block_region_settings: STRING_TABLE [STRING]
|
||||
|
||||
block_region (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8): CMS_BLOCK_REGION
|
||||
-- Region associated with block `b', or else `a_default_region' if provided.
|
||||
local
|
||||
l_region_name: detachable READABLE_STRING_8
|
||||
do
|
||||
l_region_name := block_region_settings.item (b.name)
|
||||
if l_region_name = Void then
|
||||
if a_default_region /= Void then
|
||||
l_region_name := a_default_region
|
||||
else
|
||||
-- Default .. put it in same named region
|
||||
-- Maybe a bad idea
|
||||
|
||||
l_region_name := b.name.as_lower
|
||||
end
|
||||
end
|
||||
if attached regions.item (l_region_name) as res then
|
||||
Result := res
|
||||
else
|
||||
create Result.make (l_region_name)
|
||||
regions.force (Result, l_region_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Blocks
|
||||
|
||||
add_block (b: CMS_BLOCK; a_default_region: detachable READABLE_STRING_8)
|
||||
-- Add block `b' to associated region or `a_default_region' if provided.
|
||||
local
|
||||
l_region: detachable like block_region
|
||||
do
|
||||
l_region := block_region (b, a_default_region)
|
||||
l_region.extend (b)
|
||||
end
|
||||
|
||||
|
||||
get_blocks
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("find a way to have this in configuration or database, and allow different order")
|
||||
end
|
||||
add_block (top_header_block, "top")
|
||||
add_block (header_block, "header")
|
||||
if attached message_block as m then
|
||||
add_block (m, "content")
|
||||
end
|
||||
-- FIXME: avoid hardcoded html! should be only in theme.
|
||||
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("top_content_anchor", Void, "<a id=%"main-content%"></a>%N", formats.full_html), "content")
|
||||
if attached page_title as l_page_title then
|
||||
-- FIXME: avoid hardcoded html! should be only in theme.
|
||||
add_block (create {CMS_CONTENT_BLOCK}.make_raw ("page_title", Void, "<h1 id=%"page-title%" class=%"title%">"+ l_page_title +"</h1>%N", formats.full_html), "content")
|
||||
end
|
||||
if attached primary_tabs_block as m then
|
||||
add_block (m, "content")
|
||||
end
|
||||
add_block (content_block, "content")
|
||||
|
||||
if attached management_menu_block as l_block then
|
||||
add_block (l_block, "first_sidebar")
|
||||
end
|
||||
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
|
||||
|
||||
if attached footer_block as l_block then
|
||||
add_block (l_block, "footer")
|
||||
end
|
||||
|
||||
invoke_block
|
||||
end
|
||||
|
||||
primary_menu_block: detachable CMS_MENU_BLOCK
|
||||
do
|
||||
if attached primary_menu as m and then not m.is_empty then
|
||||
create Result.make (m)
|
||||
end
|
||||
end
|
||||
|
||||
management_menu_block: detachable CMS_MENU_BLOCK
|
||||
do
|
||||
if attached management_menu as m and then not m.is_empty then
|
||||
create Result.make (m)
|
||||
end
|
||||
end
|
||||
|
||||
navigation_menu_block: detachable CMS_MENU_BLOCK
|
||||
do
|
||||
if attached navigation_menu as m and then not m.is_empty then
|
||||
create Result.make (m)
|
||||
end
|
||||
end
|
||||
|
||||
user_menu_block: detachable CMS_MENU_BLOCK
|
||||
do
|
||||
if attached user_menu as m and then not m.is_empty then
|
||||
create Result.make (m)
|
||||
end
|
||||
end
|
||||
|
||||
primary_tabs_block: detachable CMS_MENU_BLOCK
|
||||
do
|
||||
if attached primary_tabs as m and then not m.is_empty then
|
||||
create Result.make (m)
|
||||
end
|
||||
end
|
||||
|
||||
top_header_block: CMS_CONTENT_BLOCK
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
create s.make_empty
|
||||
create Result.make ("page_top", Void, s, formats.full_html)
|
||||
Result.set_is_raw (True)
|
||||
end
|
||||
|
||||
header_block: CMS_CONTENT_BLOCK
|
||||
local
|
||||
s: STRING
|
||||
l_hb: STRING
|
||||
do
|
||||
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_primary_menu_html: STRING
|
||||
do
|
||||
create Result.make_empty
|
||||
Result.append ("<div id=%"menu-bar%">")
|
||||
Result.append (theme.menu_html (primary_menu, True))
|
||||
Result.append ("</div>")
|
||||
end
|
||||
|
||||
message_html: detachable STRING
|
||||
do
|
||||
if attached message as m and then not m.is_empty then
|
||||
Result := "<div id=%"message%">" + m + "</div>"
|
||||
end
|
||||
end
|
||||
|
||||
message_block: detachable CMS_CONTENT_BLOCK
|
||||
do
|
||||
if attached message as m and then not m.is_empty then
|
||||
create Result.make ("message", Void, "<div id=%"message%">" + m + "</div>", formats.full_html)
|
||||
Result.set_is_raw (True)
|
||||
end
|
||||
end
|
||||
|
||||
content_block: CMS_CONTENT_BLOCK
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached main_content as l_content then
|
||||
s := l_content
|
||||
else
|
||||
s := ""
|
||||
debug
|
||||
s := "No Content"
|
||||
end
|
||||
end
|
||||
create Result.make ("content", Void, s, formats.full_html)
|
||||
Result.set_is_raw (True)
|
||||
end
|
||||
|
||||
made_with_html: STRING
|
||||
do
|
||||
create Result.make_empty
|
||||
Result.append ("Made with <a href=%"http://www.eiffel.com/%">EWF</a>")
|
||||
end
|
||||
|
||||
footer_block: CMS_CONTENT_BLOCK
|
||||
do
|
||||
create Result.make ("made_with", Void, made_with_html, Void)
|
||||
end
|
||||
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
hook_subscribers: HASH_TABLE [LIST [CMS_HOOK], TYPE [CMS_HOOK]]
|
||||
-- Hook indexed by hook identifier.
|
||||
|
||||
subscribe_to_hook (h: CMS_HOOK; a_hook_type: TYPE [CMS_HOOK])
|
||||
-- Subscribe `h' to hooks identified by `a_hook_type'.
|
||||
local
|
||||
lst: detachable LIST [CMS_HOOK]
|
||||
do
|
||||
lst := hook_subscribers.item (a_hook_type)
|
||||
if lst = Void then
|
||||
create {ARRAYED_LIST [CMS_HOOK]} lst.make (1)
|
||||
hook_subscribers.force (lst, a_hook_type)
|
||||
end
|
||||
if not lst.has (h) then
|
||||
lst.force (h)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: value alter
|
||||
|
||||
subscribe_to_value_table_alter_hook (h: CMS_HOOK_VALUE_TABLE_ALTER)
|
||||
-- Add `h' as subscriber of value table alter hooks CMS_HOOK_VALUE_TABLE_ALTER.
|
||||
do
|
||||
subscribe_to_hook (h, {CMS_HOOK_VALUE_TABLE_ALTER})
|
||||
end
|
||||
|
||||
invoke_value_table_alter (a_table: CMS_VALUE_TABLE)
|
||||
-- Invoke value table alter hook for table `a_table'.
|
||||
do
|
||||
if attached hook_subscribers.item ({CMS_HOOK_VALUE_TABLE_ALTER}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_VALUE_TABLE_ALTER} c.item as h then
|
||||
h.value_table_alter (a_table, Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: menu_system_alter
|
||||
|
||||
subscribe_to_menu_system_alter_hook (h: CMS_HOOK_MENU_SYSTEM_ALTER)
|
||||
-- Add `h' as subscriber of menu system alter hooks CMS_HOOK_MENU_SYSTEM_ALTER.
|
||||
do
|
||||
subscribe_to_hook (h, {CMS_HOOK_MENU_SYSTEM_ALTER})
|
||||
end
|
||||
|
||||
invoke_menu_system_alter (a_menu_system: CMS_MENU_SYSTEM)
|
||||
-- Invoke menu system alter hook for menu `a_menu_system'.
|
||||
do
|
||||
if attached hook_subscribers.item ({CMS_HOOK_MENU_SYSTEM_ALTER}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_MENU_SYSTEM_ALTER} c.item as h then
|
||||
h.menu_system_alter (a_menu_system, Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: menu_alter
|
||||
|
||||
subscribe_to_menu_alter_hook (h: CMS_HOOK_MENU_ALTER)
|
||||
-- Add `h' as subscriber of menu alter hooks CMS_HOOK_MENU_ALTER.
|
||||
do
|
||||
subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER})
|
||||
end
|
||||
|
||||
invoke_menu_alter (a_menu: CMS_MENU)
|
||||
-- Invoke menu alter hook for menu `a_menu'.
|
||||
do
|
||||
if attached hook_subscribers.item ({CMS_HOOK_MENU_ALTER}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_MENU_ALTER} c.item as h then
|
||||
h.menu_alter (a_menu, Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: form_alter
|
||||
|
||||
subscribe_to_form_alter_hook (h: CMS_HOOK_FORM_ALTER)
|
||||
-- Add `h' as subscriber of form alter hooks CMS_HOOK_FORM_ALTER.
|
||||
do
|
||||
subscribe_to_hook (h, {CMS_HOOK_MENU_ALTER})
|
||||
end
|
||||
|
||||
invoke_form_alter (a_form: CMS_FORM; a_form_data: detachable WSF_FORM_DATA)
|
||||
-- Invoke form alter hook for form `a_form' and associated data `a_form_data'
|
||||
do
|
||||
if attached hook_subscribers.item ({CMS_HOOK_FORM_ALTER}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_FORM_ALTER} c.item as h then
|
||||
h.form_alter (a_form, a_form_data, Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: block
|
||||
|
||||
subscribe_to_block_hook (h: CMS_HOOK_BLOCK)
|
||||
-- Add `h' as subscriber of hooks CMS_HOOK_BLOCK.
|
||||
do
|
||||
subscribe_to_hook (h, {CMS_HOOK_BLOCK})
|
||||
end
|
||||
|
||||
invoke_block
|
||||
-- Invoke block hook in order to get block from modules.
|
||||
do
|
||||
if attached hook_subscribers.item ({CMS_HOOK_BLOCK}) as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
if attached {CMS_HOOK_BLOCK} c.item as h then
|
||||
across
|
||||
h.block_list as blst
|
||||
loop
|
||||
h.get_block_view (blst.item, Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Menu: change
|
||||
|
||||
add_to_main_menu (lnk: CMS_LINK)
|
||||
obsolete
|
||||
"use add_to_primary_menu [Nov/2014]"
|
||||
do
|
||||
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)
|
||||
do
|
||||
-- if attached {CMS_LOCAL_LINK} lnk as l_local then
|
||||
-- l_local.get_is_active (request)
|
||||
-- end
|
||||
m.extend (lnk)
|
||||
end
|
||||
|
||||
feature -- Message
|
||||
|
||||
add_message (a_msg: READABLE_STRING_8; a_category: detachable READABLE_STRING_8)
|
||||
local
|
||||
m: like message
|
||||
do
|
||||
m := message
|
||||
if m = Void then
|
||||
create m.make (a_msg.count + 9)
|
||||
message := m
|
||||
end
|
||||
if a_category /= Void then
|
||||
m.append ("<li class=%""+ a_category +"%">")
|
||||
else
|
||||
m.append ("<li>")
|
||||
end
|
||||
m.append (a_msg + "</li>")
|
||||
end
|
||||
|
||||
add_notice_message (a_msg: READABLE_STRING_8)
|
||||
do
|
||||
add_message (a_msg, "notice")
|
||||
end
|
||||
|
||||
add_warning_message (a_msg: READABLE_STRING_8)
|
||||
do
|
||||
add_message (a_msg, "warning")
|
||||
end
|
||||
|
||||
add_error_message (a_msg: READABLE_STRING_8)
|
||||
do
|
||||
add_message (a_msg, "error")
|
||||
end
|
||||
|
||||
add_success_message (a_msg: READABLE_STRING_8)
|
||||
do
|
||||
add_message (a_msg, "success")
|
||||
end
|
||||
|
||||
report_form_errors (fd: WSF_FORM_DATA)
|
||||
require
|
||||
has_error: not fd.is_valid
|
||||
do
|
||||
if attached fd.errors as errs then
|
||||
across
|
||||
errs as err
|
||||
loop
|
||||
if attached err.item as e then
|
||||
if attached e.field as l_field then
|
||||
if attached e.message as e_msg then
|
||||
add_error_message (e_msg) --"Field [" + l_field.name + "] is invalid. " + e_msg)
|
||||
else
|
||||
add_error_message ("Field [" + l_field.name + "] is invalid.")
|
||||
end
|
||||
elseif attached e.message as e_msg then
|
||||
add_error_message (e_msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
message: detachable STRING_8
|
||||
|
||||
feature -- Theme
|
||||
|
||||
theme: CMS_THEME
|
||||
-- Current theme
|
||||
|
||||
get_theme
|
||||
local
|
||||
l_info: CMS_THEME_INFORMATION
|
||||
do
|
||||
if attached setup.theme_information_location as fn then
|
||||
create l_info.make (fn)
|
||||
else
|
||||
create l_info.make_default
|
||||
end
|
||||
if l_info.engine.is_case_insensitive_equal_general ("smarty") then
|
||||
create {SMARTY_CMS_THEME} theme.make (setup, l_info)
|
||||
else
|
||||
create {DEFAULT_CMS_THEME} theme.make (setup, l_info)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
set_status_code (a_status: INTEGER)
|
||||
-- Set `status_code' with `a_status'.
|
||||
note
|
||||
EIS: "src=eiffel:?class=HTTP_STATUS_CODE"
|
||||
do
|
||||
to_implement ("Feature to test if a_status is a valid status code!!!.")
|
||||
status_code := a_status
|
||||
ensure
|
||||
status_code_set: status_code = a_status
|
||||
end
|
||||
|
||||
feature -- Generation
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
-- Menu
|
||||
add_to_primary_menu (create {CMS_LOCAL_LINK}.make ("Home", "/"))
|
||||
invoke_menu_system_alter (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)
|
||||
|
||||
-- Cms values
|
||||
invoke_value_table_alter (values)
|
||||
|
||||
-- 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
|
||||
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 <head ../>
|
||||
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)
|
||||
-- Common preparation for page `page'.
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Fix generation common")
|
||||
end
|
||||
|
||||
-- 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
|
||||
end
|
||||
|
||||
prepare_links (a_menu: CMS_LINK_COMPOSITE)
|
||||
local
|
||||
to_remove: ARRAYED_LIST [CMS_LINK]
|
||||
do
|
||||
create to_remove.make (0)
|
||||
across
|
||||
a_menu as c
|
||||
loop
|
||||
if attached {CMS_LOCAL_LINK} c.item as lm then
|
||||
-- if attached lm.permission_arguments as perms and then not has_permissions (perms) then
|
||||
-- to_remove.force (lm)
|
||||
-- else
|
||||
-- if lm.permission_arguments is Void , this is permitted
|
||||
get_local_link_active_status (lm)
|
||||
if attached {CMS_LINK_COMPOSITE} lm as comp then
|
||||
prepare_links (comp)
|
||||
end
|
||||
-- end
|
||||
elseif attached {CMS_LINK_COMPOSITE} c.item as comp then
|
||||
prepare_links (comp)
|
||||
end
|
||||
end
|
||||
across
|
||||
to_remove as c
|
||||
loop
|
||||
a_menu.remove (c.item)
|
||||
end
|
||||
end
|
||||
|
||||
recursive_get_active (a_comp: CMS_LINK_COMPOSITE; req: WSF_REQUEST)
|
||||
-- Update the active status recursively on `a_comp'.
|
||||
local
|
||||
ln: CMS_LINK
|
||||
do
|
||||
if attached a_comp.items as l_items then
|
||||
across
|
||||
l_items as ic
|
||||
loop
|
||||
ln := ic.item
|
||||
if attached {CMS_LOCAL_LINK} ln as l_local then
|
||||
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)
|
||||
end
|
||||
end
|
||||
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
|
||||
|
||||
variables: detachable STRING_TABLE[ANY]
|
||||
-- Custom variables to feed the templates.
|
||||
|
||||
|
||||
feature -- Element change: Add custom variables.
|
||||
|
||||
add_variable (a_element: ANY; a_key:READABLE_STRING_32)
|
||||
local
|
||||
l_variables: like variables
|
||||
do
|
||||
l_variables := variables
|
||||
if l_variables = Void then
|
||||
create l_variables.make (5)
|
||||
variables := l_variables
|
||||
end
|
||||
l_variables.force (a_element, a_key)
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute
|
||||
do
|
||||
begin
|
||||
process
|
||||
terminate
|
||||
end
|
||||
|
||||
feature {NONE} -- Execution
|
||||
|
||||
begin
|
||||
do
|
||||
end
|
||||
|
||||
process
|
||||
deferred
|
||||
end
|
||||
|
||||
frozen terminate
|
||||
local
|
||||
cms_page: CMS_HTML_PAGE
|
||||
page: CMS_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create cms_page.make
|
||||
prepare (cms_page)
|
||||
create page.make (theme.page_html (cms_page))
|
||||
page.set_status_code (status_code)
|
||||
page.header.put_content_length (page.html.count)
|
||||
page.header.put_current_date
|
||||
response.send (page)
|
||||
on_terminated
|
||||
end
|
||||
|
||||
on_terminated
|
||||
do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
37
library/src/service/response/error_500_cms_response.e
Normal file
37
library/src/service/response/error_500_cms_response.e
Normal file
@@ -0,0 +1,37 @@
|
||||
note
|
||||
description: "Summary description for {ERROR_500_CMS_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ERROR_500_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.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
|
||||
page.register_variable (page.status_code.out, "code")
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
do
|
||||
set_title ("Internal Server Error")
|
||||
set_page_title (Void)
|
||||
end
|
||||
end
|
||||
|
||||
37
library/src/service/response/generic_view_cms_response.e
Normal file
37
library/src/service/response/generic_view_cms_response.e
Normal file
@@ -0,0 +1,37 @@
|
||||
note
|
||||
description: "Summary description for {NODE_VIEW_CMS_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GENERIC_VIEW_CMS_RESPONSE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
custom_prepare
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
if attached variables as l_variables then
|
||||
across l_variables as c loop page.register_variable (c.item, c.key) end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
do
|
||||
-- set_title ("CMS")
|
||||
-- set_page_title (Void)
|
||||
end
|
||||
end
|
||||
|
||||
36
library/src/service/response/home_cms_response.e
Normal file
36
library/src/service/response/home_cms_response.e
Normal file
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Summary description for {HOME_CMS_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HOME_CMS_RESPONSE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
custom_prepare
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Generation
|
||||
|
||||
custom_prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
Precursor (page)
|
||||
page.register_variable (api.recent_nodes (0, 5), "nodes")
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
do
|
||||
set_title (Void)
|
||||
set_page_title (Void)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
193
library/src/theme/cms_html_page.e
Normal file
193
library/src/theme/cms_html_page.e
Normal file
@@ -0,0 +1,193 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HTML_PAGE}."
|
||||
author: ""
|
||||
date: "$Date: 2014-11-04 09:57:24 -0300 (ma. 04 de nov. de 2014) $"
|
||||
revision: "$Revision: 96034 $"
|
||||
|
||||
class
|
||||
CMS_HTML_PAGE
|
||||
|
||||
create
|
||||
make,
|
||||
make_typed
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_typed (a_type: like type)
|
||||
-- Make current page with optional page type `a_type'.
|
||||
do
|
||||
make
|
||||
type := a_type
|
||||
end
|
||||
|
||||
make
|
||||
do
|
||||
create regions.make (5)
|
||||
language := "en"
|
||||
|
||||
status_code := {HTTP_STATUS_CODE}.ok
|
||||
create header.make
|
||||
create {ARRAYED_LIST [STRING]} head_lines.make (5)
|
||||
header.put_content_type_text_html
|
||||
create variables.make (0)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
type: detachable READABLE_STRING_8
|
||||
-- Optional page type.
|
||||
-- such as "front", "about", ... that could be customized by themes.
|
||||
|
||||
is_front: BOOLEAN
|
||||
|
||||
title: detachable READABLE_STRING_32
|
||||
|
||||
language: STRING
|
||||
|
||||
head_lines: LIST [STRING]
|
||||
|
||||
head_lines_to_string: STRING
|
||||
do
|
||||
create Result.make_empty
|
||||
across
|
||||
head_lines as h
|
||||
loop
|
||||
Result.append (h.item)
|
||||
Result.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
variables: STRING_TABLE [detachable ANY]
|
||||
|
||||
feature -- Status
|
||||
|
||||
|
||||
status_code: INTEGER
|
||||
|
||||
feature -- Header
|
||||
|
||||
header: HTTP_HEADER
|
||||
|
||||
feature -- Region
|
||||
|
||||
regions: STRING_TABLE [STRING_8]
|
||||
-- header
|
||||
-- content
|
||||
-- footer
|
||||
-- could have sidebar first, sidebar second, ...
|
||||
|
||||
region (n: STRING_8): STRING_8
|
||||
do
|
||||
if attached regions.item (n) as r then
|
||||
Result := r
|
||||
else
|
||||
Result := ""
|
||||
debug
|
||||
Result := "{{" + n + "}}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
add_to_region (s: STRING; k: STRING)
|
||||
local
|
||||
r: detachable STRING
|
||||
do
|
||||
r := regions.item (k)
|
||||
if r = Void then
|
||||
create r.make_from_string (s)
|
||||
set_region (r, k)
|
||||
else
|
||||
r.append (s)
|
||||
end
|
||||
end
|
||||
|
||||
set_region (s: STRING; k: STRING)
|
||||
do
|
||||
regions.force (s, k)
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_status_code (c: like status_code)
|
||||
do
|
||||
status_code := c
|
||||
end
|
||||
|
||||
set_language (s: like language)
|
||||
do
|
||||
language := s
|
||||
end
|
||||
|
||||
set_title (s: like title)
|
||||
do
|
||||
title := s
|
||||
end
|
||||
|
||||
add_meta_name_content (a_name: STRING; a_content: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<meta name=%"" + a_name + "%" content=%"" + a_content + "%" />"
|
||||
head_lines.extend (s)
|
||||
end
|
||||
|
||||
add_meta_http_equiv (a_http_equiv: STRING; a_content: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<meta http-equiv=%"" + a_http_equiv + "%" content=%"" + a_content + "%" />"
|
||||
head_lines.extend (s)
|
||||
end
|
||||
|
||||
add_style (a_href: STRING; a_media: detachable STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<link rel=%"stylesheet%" href=%""+ a_href + "%" type=%"text/css%""
|
||||
if a_media /= Void then
|
||||
s.append (" media=%""+ a_media + "%"")
|
||||
end
|
||||
s.append ("/>")
|
||||
head_lines.extend (s)
|
||||
end
|
||||
|
||||
add_javascript_url (a_src: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<script type=%"text/javascript%" src=%"" + a_src + "%"></script>"
|
||||
head_lines.extend (s)
|
||||
end
|
||||
|
||||
add_javascript_content (a_script: STRING)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
s := "<script type=%"text/javascript%">%N" + a_script + "%N</script>"
|
||||
head_lines.extend (s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
77
library/src/theme/cms_html_page_response.e
Normal file
77
library/src/theme/cms_html_page_response.e
Normal file
@@ -0,0 +1,77 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HTML_PAGE_RESPONSE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_HTML_PAGE_RESPONSE
|
||||
|
||||
inherit
|
||||
WSF_RESPONSE_MESSAGE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_html: like html)
|
||||
do
|
||||
html := a_html
|
||||
status_code := {HTTP_STATUS_CODE}.ok
|
||||
create header.make
|
||||
header.put_content_type_text_html
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
status_code: INTEGER
|
||||
|
||||
feature -- Header
|
||||
|
||||
header: HTTP_HEADER
|
||||
|
||||
feature -- Html access
|
||||
|
||||
html: STRING
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_status_code (c: like status_code)
|
||||
do
|
||||
status_code := c
|
||||
end
|
||||
|
||||
feature {WSF_RESPONSE} -- Output
|
||||
|
||||
send_to (res: WSF_RESPONSE)
|
||||
local
|
||||
h: like header
|
||||
s: STRING_8
|
||||
do
|
||||
h := header
|
||||
res.set_status_code (status_code)
|
||||
s := html
|
||||
|
||||
if not h.has_content_length then
|
||||
h.put_content_length (s.count)
|
||||
end
|
||||
if not h.has_content_type then
|
||||
h.put_content_type_text_html
|
||||
end
|
||||
res.put_header_text (h.string)
|
||||
res.put_string (s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
13
library/src/theme/cms_html_template.e
Normal file
13
library/src/theme/cms_html_template.e
Normal file
@@ -0,0 +1,13 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CMS_HTML_TEMPLATE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_HTML_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_TEMPLATE
|
||||
|
||||
end
|
||||
12
library/src/theme/cms_page_template.e
Normal file
12
library/src/theme/cms_page_template.e
Normal file
@@ -0,0 +1,12 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PAGE_TEMPLATE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_PAGE_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_TEMPLATE
|
||||
end
|
||||
37
library/src/theme/cms_template.e
Normal file
37
library/src/theme/cms_template.e
Normal file
@@ -0,0 +1,37 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CMS_PAGE_TEMPLATE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_TEMPLATE
|
||||
|
||||
feature -- Access
|
||||
|
||||
theme: CMS_THEME
|
||||
deferred
|
||||
end
|
||||
|
||||
variables: STRING_TABLE [detachable ANY]
|
||||
deferred
|
||||
end
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
deferred
|
||||
end
|
||||
|
||||
to_html (page: CMS_HTML_PAGE): STRING
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
138
library/src/theme/cms_theme.e
Normal file
138
library/src/theme/cms_theme.e
Normal file
@@ -0,0 +1,138 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CMS_THEME}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_THEME
|
||||
|
||||
inherit
|
||||
CMS_ENCODERS
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
|
||||
feature {NONE} -- Access
|
||||
|
||||
setup: CMS_SETUP
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING
|
||||
-- theme name.
|
||||
deferred
|
||||
end
|
||||
|
||||
regions: ARRAY [STRING]
|
||||
-- theme's regions.
|
||||
deferred
|
||||
end
|
||||
|
||||
page_template: CMS_TEMPLATE
|
||||
-- theme template page.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
menu_html (a_menu: CMS_MENU; is_horizontal: BOOLEAN): STRING_8
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Refactor HTML code to use the new Bootstrap theme template")
|
||||
end
|
||||
create Result.make_from_string ("<div id=%""+ a_menu.name +"%" class=%"menu%">")
|
||||
if is_horizontal then
|
||||
Result.append ("<ul class=%"horizontal%" >%N")
|
||||
else
|
||||
Result.append ("<ul class=%"vertical%" >%N")
|
||||
end
|
||||
across
|
||||
a_menu as c
|
||||
loop
|
||||
append_cms_link_to (c.item, Result)
|
||||
end
|
||||
Result.append ("</ul>%N")
|
||||
Result.append ("</div>")
|
||||
end
|
||||
|
||||
block_html (a_block: CMS_BLOCK): STRING_8
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Refactor HTML code to use the new Bootstrap theme template")
|
||||
end
|
||||
if attached {CMS_CONTENT_BLOCK} a_block as l_content_block and then l_content_block.is_raw then
|
||||
create s.make_empty
|
||||
if attached l_content_block.title as l_title then
|
||||
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
|
||||
end
|
||||
s.append (l_content_block.to_html (Current))
|
||||
else
|
||||
create s.make_from_string ("<div class=%"block%" id=%"" + a_block.name + "%">")
|
||||
if attached a_block.title as l_title then
|
||||
s.append ("<div class=%"title%">" + html_encoded (l_title) + "</div>")
|
||||
end
|
||||
s.append ("<div class=%"inside%">")
|
||||
s.append (a_block.to_html (Current))
|
||||
s.append ("</div>")
|
||||
s.append ("</div>")
|
||||
end
|
||||
Result := s
|
||||
end
|
||||
page_html (page: CMS_HTML_PAGE): STRING_8
|
||||
-- Render `page' as html.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
append_cms_link_to (lnk: CMS_LINK; s: STRING_8)
|
||||
local
|
||||
cl: STRING
|
||||
do
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Remove HTML from Eiffel")
|
||||
end
|
||||
create cl.make_empty
|
||||
if lnk.is_active then
|
||||
cl.append ("active ")
|
||||
end
|
||||
if lnk.is_expandable then
|
||||
cl.append ("expandable ")
|
||||
end
|
||||
if lnk.is_expanded then
|
||||
cl.append ("expanded ")
|
||||
end
|
||||
if cl.is_empty then
|
||||
s.append ("<li>")
|
||||
else
|
||||
s.append ("<li class=%""+ cl + "%">")
|
||||
end
|
||||
s.append ("<a href=%"" + (lnk.location) + "%">" + html_encoded (lnk.title) + "</a>")
|
||||
if
|
||||
(lnk.is_expanded or lnk.is_collapsed) and then
|
||||
attached lnk.children as l_children
|
||||
then
|
||||
s.append ("<ul>%N")
|
||||
across
|
||||
l_children as c
|
||||
loop
|
||||
append_cms_link_to (c.item, s)
|
||||
end
|
||||
s.append ("</ul>")
|
||||
end
|
||||
s.append ("</li>")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
135
library/src/theme/cms_theme_information.e
Normal file
135
library/src/theme/cms_theme_information.e
Normal file
@@ -0,0 +1,135 @@
|
||||
note
|
||||
description: "Summary description for {CMS_THEME_INFORMATION}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_THEME_INFORMATION
|
||||
|
||||
create
|
||||
make,
|
||||
make_default
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_default
|
||||
do
|
||||
engine := {STRING_32} "default"
|
||||
create items.make_caseless (1)
|
||||
create regions.make (5)
|
||||
across
|
||||
(<<"top","header", "highlighted","help", "content", "footer", "first_sidebar", "second_sidebar", "bottom">>) as ic
|
||||
loop
|
||||
regions.force (ic.item, ic.item)
|
||||
end
|
||||
end
|
||||
|
||||
make (fn: PATH)
|
||||
local
|
||||
f: PLAIN_TEXT_FILE
|
||||
s: STRING_8
|
||||
h,k: STRING_8
|
||||
v: STRING_32
|
||||
i: INTEGER
|
||||
utf: UTF_CONVERTER
|
||||
l_engine: detachable READABLE_STRING_32
|
||||
done: BOOLEAN
|
||||
do
|
||||
make_default
|
||||
create f.make_with_path (fn)
|
||||
if f.exists and then f.is_access_readable then
|
||||
f.open_read
|
||||
from
|
||||
until
|
||||
done or f.exhausted or f.end_of_file
|
||||
loop
|
||||
f.read_line_thread_aware
|
||||
s := f.last_string
|
||||
s.left_adjust
|
||||
if
|
||||
s.is_empty
|
||||
or else s.starts_with_general (";")
|
||||
or else s.starts_with_general ("#")
|
||||
or else s.starts_with_general ("--")
|
||||
then
|
||||
-- Ignore
|
||||
else
|
||||
i := s.index_of ('=', 1)
|
||||
if i > 0 then
|
||||
h := s.substring (1, i - 1)
|
||||
h.left_adjust
|
||||
h.right_adjust
|
||||
if h.is_case_insensitive_equal_general ("engine") then
|
||||
s.remove_head (i)
|
||||
s.right_adjust
|
||||
v := utf.utf_8_string_8_to_string_32 (s)
|
||||
l_engine := v
|
||||
elseif h.starts_with_general ("regions[") and h[h.count] = ']' then
|
||||
s.remove_head (i)
|
||||
s.right_adjust
|
||||
v := utf.utf_8_string_8_to_string_32 (s)
|
||||
i := h.index_of ('[', 1)
|
||||
k := h.substring (i + 1, h.count - 1)
|
||||
k.left_adjust
|
||||
k.right_adjust
|
||||
if k.starts_with_general ("-") then
|
||||
--| If name is prefixed by "-"
|
||||
--| remove the related region
|
||||
--| If name is "-*", clear all regions.
|
||||
if k.is_case_insensitive_equal_general ("-*") then
|
||||
regions.wipe_out
|
||||
else
|
||||
k.remove_head (1)
|
||||
regions.remove (k)
|
||||
end
|
||||
else
|
||||
regions.force (v, k)
|
||||
end
|
||||
else
|
||||
s.remove_head (i)
|
||||
s.right_adjust
|
||||
v := utf.utf_8_string_8_to_string_32 (s)
|
||||
end
|
||||
items.force (v, h)
|
||||
end
|
||||
end
|
||||
end
|
||||
f.close
|
||||
end
|
||||
if l_engine /= Void and then not l_engine.is_empty then
|
||||
engine := l_engine
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
engine: STRING_32
|
||||
-- Template engine.
|
||||
--| Could be: default, smarty, ...
|
||||
|
||||
regions: STRING_TABLE [READABLE_STRING_GENERAL]
|
||||
-- Regions available in this theme
|
||||
|
||||
item (k: READABLE_STRING_GENERAL): detachable STRING_32
|
||||
-- Item associated with name `k' if any.
|
||||
do
|
||||
Result := items[k]
|
||||
end
|
||||
|
||||
items: STRING_TABLE [STRING_32]
|
||||
-- Items indexed by key name.
|
||||
|
||||
invariant
|
||||
engine_set: not engine.is_empty
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
75
library/src/theme/default_cms_template.e
Normal file
75
library/src/theme/default_cms_template.e
Normal file
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_CMS_TEMPLATE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
DEFAULT_CMS_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_TEMPLATE
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
apply_template_engine (s: STRING_8)
|
||||
local
|
||||
p,n: INTEGER
|
||||
k: STRING
|
||||
sv: detachable STRING
|
||||
do
|
||||
from
|
||||
n := s.count
|
||||
p := 1
|
||||
until
|
||||
p = 0
|
||||
loop
|
||||
p := s.index_of ('$', p)
|
||||
if p > 0 then
|
||||
k := next_identifier (s, p + 1)
|
||||
s.remove_substring (p, p + k.count)
|
||||
sv := Void
|
||||
if attached variables.item (k) as l_value then
|
||||
|
||||
if attached {STRING_8} l_value as s8 then
|
||||
sv := s8
|
||||
elseif attached {STRING_32} l_value as s32 then
|
||||
sv := s32.as_string_8 -- FIXME: use html encoder
|
||||
else
|
||||
sv := l_value.out
|
||||
end
|
||||
s.insert_string (sv, p)
|
||||
p := p + sv.count
|
||||
else
|
||||
debug
|
||||
s.insert_string ("$" + k, p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
next_identifier (s: STRING; a_index: INTEGER): STRING
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
from
|
||||
i := a_index
|
||||
until
|
||||
not (s[i].is_alpha_numeric or s[i] = '_' or s[i] = '.')
|
||||
loop
|
||||
i := i + 1
|
||||
end
|
||||
Result := s.substring (a_index, i - 1)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
100
library/src/theme/default_theme/default_cms_html_template.e
Normal file
100
library/src/theme/default_theme/default_cms_html_template.e
Normal file
@@ -0,0 +1,100 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HTML_TEMPLATE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
DEFAULT_CMS_HTML_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_HTML_TEMPLATE
|
||||
|
||||
DEFAULT_CMS_TEMPLATE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (t: DEFAULT_CMS_THEME)
|
||||
do
|
||||
theme := t
|
||||
create variables.make (0)
|
||||
end
|
||||
|
||||
variables: STRING_TABLE [detachable ANY]
|
||||
|
||||
feature -- Access
|
||||
|
||||
register (v: STRING_8; k: STRING_8)
|
||||
do
|
||||
variables.force (v, k)
|
||||
end
|
||||
|
||||
theme: DEFAULT_CMS_THEME
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
variables.make (10)
|
||||
|
||||
across
|
||||
page.variables as ic
|
||||
loop
|
||||
variables.force (ic.item, ic.key)
|
||||
end
|
||||
|
||||
if attached page.title as l_title then
|
||||
variables.force (l_title, "title")
|
||||
variables.force (l_title, "head_title")
|
||||
else
|
||||
variables.force ("", "title")
|
||||
variables.force ("", "head_title")
|
||||
end
|
||||
|
||||
variables.force (page.language, "language")
|
||||
variables.force (page.head_lines_to_string, "head_lines")
|
||||
end
|
||||
|
||||
to_html (page: CMS_HTML_PAGE): STRING
|
||||
do
|
||||
-- Process html generation
|
||||
create Result.make_from_string (template)
|
||||
apply_template_engine (Result)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
template: STRING
|
||||
once
|
||||
Result := "[
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="$language" lang="$language" version="XHTML+RDFa 1.0" dir="ltr">
|
||||
<head>
|
||||
$head
|
||||
<title>$head_title</title>
|
||||
$styles
|
||||
$scripts
|
||||
$head_lines
|
||||
</head>
|
||||
<body class="$body_classes" $body_attributes>
|
||||
$page_top
|
||||
$page
|
||||
$page_bottom
|
||||
</body>
|
||||
</html>
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
102
library/src/theme/default_theme/default_cms_page_template.e
Normal file
102
library/src/theme/default_theme/default_cms_page_template.e
Normal file
@@ -0,0 +1,102 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PAGE_TEMPLATE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
DEFAULT_CMS_PAGE_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_PAGE_TEMPLATE
|
||||
|
||||
DEFAULT_CMS_TEMPLATE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (t: DEFAULT_CMS_THEME)
|
||||
do
|
||||
theme := t
|
||||
create variables.make (0)
|
||||
end
|
||||
|
||||
variables: STRING_TABLE [detachable ANY]
|
||||
|
||||
feature -- Access
|
||||
|
||||
theme: DEFAULT_CMS_THEME
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
variables.make (10)
|
||||
|
||||
across
|
||||
page.variables as ic
|
||||
loop
|
||||
variables.force (ic.item, ic.key)
|
||||
end
|
||||
|
||||
if attached page.title as l_title then
|
||||
variables.force (l_title, "title")
|
||||
else
|
||||
variables.force ("", "title")
|
||||
end
|
||||
across
|
||||
theme.regions as r
|
||||
loop
|
||||
variables.force (page.region (r.item), r.item)
|
||||
end
|
||||
end
|
||||
|
||||
to_html (page: CMS_HTML_PAGE): STRING
|
||||
do
|
||||
-- Process html generation
|
||||
create Result.make_from_string (template)
|
||||
apply_template_engine (Result)
|
||||
end
|
||||
|
||||
feature -- Registration
|
||||
|
||||
register (v: STRING_8; k: STRING_8)
|
||||
do
|
||||
variables.force (v, k)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
template: STRING
|
||||
once
|
||||
Result := "[
|
||||
<div id="page-wrapper">
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
$header
|
||||
</div>
|
||||
<div id="main-wrapper">
|
||||
<div id="main">
|
||||
<div id="first_sidebar" class="sidebar $first_sidebar_css_class">$first_sidebar</div>
|
||||
<div id="content" class="$content_css_class">$content</div>
|
||||
<div id="second_sidebar" class="sidebar $second_sidebar_css_class">$second_sidebar</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">$footer</div>
|
||||
</div>
|
||||
</div>
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
100
library/src/theme/default_theme/default_cms_theme.e
Normal file
100
library/src/theme/default_theme/default_cms_theme.e
Normal file
@@ -0,0 +1,100 @@
|
||||
note
|
||||
description: "Summary description for {CMS_THEME}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
DEFAULT_CMS_THEME
|
||||
|
||||
inherit
|
||||
CMS_THEME
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: like setup; a_info: like information)
|
||||
do
|
||||
setup := a_setup
|
||||
information := a_info
|
||||
end
|
||||
|
||||
information: CMS_THEME_INFORMATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "CMS"
|
||||
|
||||
regions: ARRAY [STRING]
|
||||
once
|
||||
Result := <<"header", "content", "footer", "first_sidebar", "second_sidebar">>
|
||||
end
|
||||
|
||||
html_template: DEFAULT_CMS_HTML_TEMPLATE
|
||||
local
|
||||
tpl: like internal_html_template
|
||||
do
|
||||
tpl := internal_html_template
|
||||
if tpl = Void then
|
||||
create tpl.make (Current)
|
||||
internal_html_template := tpl
|
||||
end
|
||||
Result := tpl
|
||||
end
|
||||
|
||||
page_template: DEFAULT_CMS_PAGE_TEMPLATE
|
||||
local
|
||||
tpl: like internal_page_template
|
||||
do
|
||||
tpl := internal_page_template
|
||||
if tpl = Void then
|
||||
create tpl.make (Current)
|
||||
internal_page_template := tpl
|
||||
end
|
||||
Result := tpl
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
end
|
||||
|
||||
page_html (page: CMS_HTML_PAGE): STRING_8
|
||||
local
|
||||
l_content: STRING_8
|
||||
do
|
||||
prepare (page)
|
||||
page_template.prepare (page)
|
||||
l_content := page_template.to_html (page)
|
||||
html_template.prepare (page)
|
||||
html_template.register (l_content, "page")
|
||||
Result := html_template.to_html (page)
|
||||
end
|
||||
|
||||
navigation_template: detachable READABLE_STRING_GENERAL
|
||||
-- navigation template name, if any.
|
||||
do
|
||||
end
|
||||
|
||||
feature {NONE} -- Internal
|
||||
|
||||
internal_page_template: detachable like page_template
|
||||
|
||||
internal_html_template: detachable like html_template
|
||||
|
||||
invariant
|
||||
attached internal_page_template as inv_p implies inv_p.theme = Current
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "Summary description for {SMARTY_CMS_HTML_PAGE_INSPECTOR}."
|
||||
author: ""
|
||||
date: "$Date: 2014-11-07 04:58:41 -0300 (vi. 07 de nov. de 2014) $"
|
||||
revision: "$Revision: 96042 $"
|
||||
|
||||
class
|
||||
SMARTY_CMS_HTML_PAGE_INSPECTOR
|
||||
|
||||
inherit
|
||||
TEMPLATE_INSPECTOR
|
||||
redefine
|
||||
internal_data
|
||||
end
|
||||
|
||||
CMS_ENCODERS
|
||||
|
||||
create
|
||||
register
|
||||
|
||||
feature {TEMPLATE_ROUTINES}
|
||||
|
||||
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
|
||||
-- Return object in a cell
|
||||
-- If not handled by this inspector, return Void
|
||||
local
|
||||
l_fn: STRING
|
||||
do
|
||||
if attached {CMS_HTML_PAGE} obj as l_page then
|
||||
l_fn := field_name.as_lower
|
||||
if attached l_page.variables.item (l_fn) as v then
|
||||
Result := cell_of (v)
|
||||
elseif l_fn.is_case_insensitive_equal ("title") then
|
||||
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))
|
||||
elseif l_fn.is_case_insensitive_equal ("regions") then
|
||||
Result := cell_of (l_page.regions)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
137
library/src/theme/smarty_theme/smarty_cms_page_template.e
Normal file
137
library/src/theme/smarty_theme/smarty_cms_page_template.e
Normal file
@@ -0,0 +1,137 @@
|
||||
note
|
||||
description: "Summary description for {CMS_PAGE_TEMPLATE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
SMARTY_CMS_PAGE_TEMPLATE
|
||||
|
||||
inherit
|
||||
CMS_PAGE_TEMPLATE
|
||||
|
||||
CMS_ENCODERS
|
||||
|
||||
SHARED_TEMPLATE_CONTEXT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (tpl: READABLE_STRING_GENERAL; t: SMARTY_CMS_THEME)
|
||||
do
|
||||
theme := t
|
||||
create variables.make (0)
|
||||
template_name := tpl
|
||||
end
|
||||
|
||||
variables: STRING_TABLE [detachable ANY]
|
||||
|
||||
feature -- Access
|
||||
|
||||
template_name: READABLE_STRING_GENERAL
|
||||
|
||||
theme: SMARTY_CMS_THEME
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
variables.make (10)
|
||||
|
||||
across
|
||||
page.variables as ic
|
||||
loop
|
||||
variables.force (ic.item, ic.key)
|
||||
end
|
||||
|
||||
-- FIXME: review variables !
|
||||
if attached page.title as l_title then
|
||||
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")
|
||||
end
|
||||
|
||||
variables.force (page.language, "language")
|
||||
variables.force (page.head_lines_to_string, "head_lines")
|
||||
|
||||
across
|
||||
theme.regions as r
|
||||
loop
|
||||
variables.force (page.region (r.item), "region_" + r.item)
|
||||
end
|
||||
end
|
||||
|
||||
to_html (page: CMS_HTML_PAGE): STRING
|
||||
local
|
||||
tpl: detachable TEMPLATE_FILE
|
||||
ut: FILE_UTILITIES
|
||||
p: detachable PATH
|
||||
n: STRING_32
|
||||
do
|
||||
-- Process html generation
|
||||
template_context.set_template_folder (theme.templates_directory)
|
||||
template_context.disable_verbose
|
||||
debug ("smarty")
|
||||
template_context.enable_verbose
|
||||
end
|
||||
p := template_context.template_folder
|
||||
if p = Void then
|
||||
create p.make_current
|
||||
end
|
||||
if attached page.type as l_page_type then
|
||||
create n.make_from_string_general (l_page_type)
|
||||
n.append_character ('-')
|
||||
n.append_string_general (template_name)
|
||||
n.append_string_general (".tpl")
|
||||
if ut.file_path_exists (p.extended (n)) then
|
||||
create tpl.make_from_file (n)
|
||||
end
|
||||
end
|
||||
if tpl = Void then
|
||||
create n.make_from_string_general (template_name)
|
||||
n.append_string_general (".tpl")
|
||||
if ut.file_path_exists (p.extended (n)) then
|
||||
create tpl.make_from_file (n)
|
||||
end
|
||||
end
|
||||
if tpl /= Void then
|
||||
across
|
||||
variables as ic
|
||||
loop
|
||||
tpl.add_value (ic.item, ic.key)
|
||||
end
|
||||
|
||||
debug ("cms")
|
||||
template_context.enable_verbose
|
||||
end
|
||||
tpl.analyze
|
||||
tpl.get_output
|
||||
if attached tpl.output as l_output then
|
||||
Result := l_output
|
||||
else
|
||||
create Result.make_from_string ("ERROR: template issue.")
|
||||
end
|
||||
else
|
||||
create Result.make_from_string ("ERROR: template issue.")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Registration
|
||||
|
||||
register (v: STRING_8; k: STRING_8)
|
||||
do
|
||||
variables.force (v, k)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "Summary description for {SMARTY_CMS_REGIONS_INSPECTOR}."
|
||||
author: ""
|
||||
date: "$Date: 2014-11-06 17:59:12 -0300 (ju. 06 de nov. de 2014) $"
|
||||
revision: "$Revision: 96040 $"
|
||||
|
||||
class
|
||||
SMARTY_CMS_REGIONS_INSPECTOR
|
||||
|
||||
inherit
|
||||
TEMPLATE_INSPECTOR
|
||||
redefine
|
||||
internal_data
|
||||
end
|
||||
|
||||
create
|
||||
register
|
||||
|
||||
feature {TEMPLATE_ROUTINES}
|
||||
|
||||
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
|
||||
-- Return object in a cell
|
||||
-- If not handled by this inspector, return Void
|
||||
local
|
||||
l_fn: STRING
|
||||
do
|
||||
if attached {like {CMS_RESPONSE}.regions} obj as l_regions then
|
||||
l_fn := field_name.as_lower
|
||||
if l_fn.is_case_insensitive_equal ("count") then
|
||||
Result := cell_of (l_regions.count)
|
||||
elseif l_regions.has (l_fn) then
|
||||
Result := cell_of (l_regions.item (l_fn))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
137
library/src/theme/smarty_theme/smarty_cms_theme.e
Normal file
137
library/src/theme/smarty_theme/smarty_cms_theme.e
Normal file
@@ -0,0 +1,137 @@
|
||||
note
|
||||
description: "Summary description for {SMARTY_CMS_THEME}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
SMARTY_CMS_THEME
|
||||
|
||||
inherit
|
||||
CMS_THEME
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: like setup; a_info: like information;)
|
||||
do
|
||||
setup := a_setup
|
||||
information := a_info
|
||||
if attached a_info.item ("template_dir") as s then
|
||||
templates_directory := a_setup.theme_location.extended (s)
|
||||
else
|
||||
templates_directory := a_setup.theme_location
|
||||
end
|
||||
ensure
|
||||
setup_set: setup = a_setup
|
||||
information_set: information = a_info
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "smarty-CMS"
|
||||
|
||||
templates_directory: PATH
|
||||
|
||||
information: CMS_THEME_INFORMATION
|
||||
|
||||
regions: ARRAY [STRING]
|
||||
local
|
||||
i: INTEGER
|
||||
utf: UTF_CONVERTER
|
||||
l_regions: like internal_regions
|
||||
do
|
||||
l_regions := internal_regions
|
||||
if l_regions = Void then
|
||||
if attached information.regions as tb and then not tb.is_empty then
|
||||
i := 1
|
||||
create l_regions.make_filled ("", i, i + tb.count - 1)
|
||||
across
|
||||
tb as ic
|
||||
loop
|
||||
l_regions.force (utf.utf_32_string_to_utf_8_string_8 (ic.key), i) -- NOTE: UTF-8 encoded !
|
||||
i := i + 1
|
||||
end
|
||||
else
|
||||
l_regions := <<"top","header", "content", "footer", "first_sidebar", "second_sidebar","bottom">>
|
||||
end
|
||||
internaL_regions := l_regions
|
||||
end
|
||||
Result := l_regions
|
||||
end
|
||||
|
||||
page_template: SMARTY_CMS_PAGE_TEMPLATE
|
||||
local
|
||||
tpl: like internal_page_template
|
||||
do
|
||||
tpl := internal_page_template
|
||||
if tpl = Void then
|
||||
create tpl.make ("page", Current)
|
||||
internal_page_template := tpl
|
||||
end
|
||||
Result := tpl
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
prepare (page: CMS_HTML_PAGE)
|
||||
do
|
||||
page.register_variable (page, "page")
|
||||
page.register_variable (page.regions, "regions")
|
||||
across
|
||||
page.regions as ic
|
||||
loop
|
||||
page.register_variable (ic.item, "region_" + ic.key)
|
||||
end
|
||||
end
|
||||
|
||||
page_html (page: CMS_HTML_PAGE): STRING_8
|
||||
local
|
||||
l_page_inspector: detachable SMARTY_CMS_HTML_PAGE_INSPECTOR
|
||||
l_regions_inspector: detachable SMARTY_CMS_REGIONS_INSPECTOR
|
||||
l_table_inspector: detachable STRING_TABLE_OF_STRING_INSPECTOR
|
||||
do
|
||||
prepare (page)
|
||||
create l_page_inspector.register (page.generating_type)
|
||||
|
||||
if attached {CMS_RESPONSE} page.variables.item ("cms") as l_cms then
|
||||
if attached l_cms.regions as l_regions then
|
||||
create l_regions_inspector.register (l_regions.generating_type)
|
||||
end
|
||||
end
|
||||
|
||||
create l_table_inspector.register (({detachable STRING_TABLE [STRING]}).name)
|
||||
page_template.prepare (page)
|
||||
Result := page_template.to_html (page)
|
||||
|
||||
-- Clean template inspector.
|
||||
if l_regions_inspector /= Void then
|
||||
l_regions_inspector.unregister
|
||||
end
|
||||
if l_page_inspector /= Void then
|
||||
l_page_inspector.unregister
|
||||
end
|
||||
l_table_inspector.unregister
|
||||
end
|
||||
|
||||
feature {NONE} -- Internal
|
||||
|
||||
internal_regions: detachable like regions
|
||||
|
||||
internal_page_template: detachable like page_template
|
||||
|
||||
invariant
|
||||
attached internal_page_template as inv_p implies inv_p.theme = Current
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "Summary description for {STRING_TABLE_OF_STRING_INSPECTOR}."
|
||||
author: ""
|
||||
date: "$Date: 2014-11-06 17:59:12 -0300 (ju. 06 de nov. de 2014) $"
|
||||
revision: "$Revision: 96040 $"
|
||||
|
||||
class
|
||||
STRING_TABLE_OF_STRING_INSPECTOR
|
||||
|
||||
inherit
|
||||
TEMPLATE_INSPECTOR
|
||||
redefine
|
||||
internal_data
|
||||
end
|
||||
|
||||
create
|
||||
register
|
||||
|
||||
feature {TEMPLATE_ROUTINES}
|
||||
|
||||
internal_data (field_name: STRING; obj: detachable ANY): detachable CELL [detachable ANY]
|
||||
-- Return object in a cell
|
||||
-- If not handled by this inspector, return Void
|
||||
local
|
||||
l_fn: STRING
|
||||
do
|
||||
if attached {STRING_TABLE [STRING]} obj as l_regions then
|
||||
l_fn := field_name.as_lower
|
||||
if l_fn.is_case_insensitive_equal ("count") then
|
||||
Result := cell_of (l_regions.count)
|
||||
elseif attached l_regions.item (l_fn) as v then
|
||||
Result := cell_of (v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
Reference in New Issue
Block a user