Updated CMS code.

Separated code to have a lib and an example.
Improved design, fixed a few issues related to folder location.

This is still experimental and require more work to be really friendly to use.
This commit is contained in:
Jocelyn Fiat
2013-01-31 15:33:24 +01:00
parent 40ea982293
commit ce469b6ede
136 changed files with 1841 additions and 299 deletions

View File

@@ -0,0 +1,75 @@
note
description: "Summary description for {CMS_API_OPTIONS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_API_OPTIONS
create
make,
make_from_manifest
convert
make_from_manifest ({ ARRAY [TUPLE [key: STRING; value: detachable ANY]],
ARRAY [TUPLE [STRING_8, ARRAY [TUPLE [STRING_8, READABLE_STRING_32]]]]
})
feature {NONE} -- Initialization
make (n: INTEGER)
do
create table.make (n)
end
make_from_manifest (lst: ARRAY [TUPLE [key: STRING; value: detachable ANY]])
do
make (lst.count)
across
lst as c
loop
force (c.item.value, c.item.key)
end
end
feature -- Access
item (k: STRING): detachable ANY
do
Result := table.item (k)
end
force (v: detachable ANY; k: STRING)
do
table.force (v, k)
end
boolean_item (k: STRING; dft: BOOLEAN): BOOLEAN
do
if attached {BOOLEAN} item (k) as b then
Result := b
else
Result := dft
end
end
string_general_item (k: STRING): detachable READABLE_STRING_GENERAL
do
if attached {READABLE_STRING_GENERAL} item (k) as s then
Result := s
end
end
string_item, string_8_item (k: STRING): detachable READABLE_STRING_8
do
if attached {READABLE_STRING_8} item (k) as s then
Result := s
end
end
table: HASH_TABLE [detachable ANY, STRING]
invariant
end

View File

@@ -0,0 +1,225 @@
note
description: "Summary description for {WSF_CMS_COMMON_API}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_COMMON_API
feature {NONE} -- Access
service: CMS_SERVICE
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)
Result.append (p)
else
Result := p
end
end
feature -- Access
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
link (a_text: detachable READABLE_STRING_GENERAL; a_path: STRING; opts: detachable CMS_API_OPTIONS): STRING
local
l_html: BOOLEAN
t: READABLE_STRING_GENERAL
do
l_html := True
if opts /= Void then
l_html := opts.boolean_item ("html", l_html)
end
Result := "<a href=%"" + checked_url (url (a_path, opts)) + "%">"
if a_text = Void then
t := a_path
else
t := a_text
end
if l_html then
Result.append (html_encoded (t))
else
Result.append (checked_plain (t))
end
Result.append ("</a>")
end
link_with_raw_text (a_text: detachable READABLE_STRING_8; a_path: STRING; opts: detachable CMS_API_OPTIONS): STRING
local
l_html: BOOLEAN
t: READABLE_STRING_8
do
l_html := True
if opts /= Void then
l_html := opts.boolean_item ("html", l_html)
end
Result := "<a href=%"" + checked_url (url (a_path, opts)) + "%">"
if a_text = Void then
t := a_path
else
t := a_text
end
Result.append (t)
Result.append ("</a>")
end
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
url (a_path: STRING; opts: detachable CMS_API_OPTIONS): STRING
local
q,f: detachable STRING_8
l_abs: BOOLEAN
do
l_abs := False
Result := based_path (a_path)
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 q /= Void then
Result.append ("?" + q)
end
if f /= Void then
Result.append ("#" + f)
end
if l_abs then
if Result.substring_index ("://", 1) = 0 then
Result.prepend (service.site_url)
end
end
end
checked_url (a_url: STRING): STRING
do
Result := a_url
end
checked_plain (a_text: READABLE_STRING_GENERAL): STRING_8
do
Result := html_encoder.general_encoded_string (a_text)
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

View File

@@ -0,0 +1,25 @@
note
description: "Summary description for {CMS_URL_API_OPTIONS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_URL_API_OPTIONS
inherit
CMS_API_OPTIONS
create
make,
make_absolute
feature {NONE} -- Initialization
make_absolute
do
make (1)
force (True, "absolute")
end
end

View File

@@ -0,0 +1,16 @@
note
description: "Summary description for {CMS_AUTH_ENGINE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_AUTH_ENGINE
feature -- Status
valid_credential (u,p: READABLE_STRING_32): BOOLEAN
deferred
end
end

View File

@@ -0,0 +1,32 @@
note
description: "Summary description for {CMS_STORAGE_AUTH_ENGINE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_STORAGE_AUTH_ENGINE
inherit
CMS_AUTH_ENGINE
create
make
feature {NONE} -- Initialization
make (a_storage: like storage)
do
storage := a_storage
end
storage: CMS_STORAGE
feature -- Status
valid_credential (u,p: READABLE_STRING_32): BOOLEAN
do
Result := storage.is_valid_credential (u, p)
end
end

View File

@@ -0,0 +1,65 @@
note
description: "Summary description for {CMS_CSS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_CSS
create
make
feature {NONE} -- Initialization
make
do
create items.make (3)
end
feature -- Access
items: ARRAYED_LIST [TUPLE [selectors: ITERABLE [CMS_CSS_SELECTOR]; style: CMS_CSS_STYLE]]
feature -- Conversion
string: READABLE_STRING_8
local
s: STRING_8
do
create s.make (64)
append_to (s)
Result := s
end
append_to (a_target: STRING_8)
local
s: STRING_8
s_selectors: STRING_8
do
create s.make (64)
create s_selectors.make (10)
across
items as c
loop
s_selectors.wipe_out
across
c.item.selectors as cs
loop
if not s_selectors.is_empty then
s_selectors.append_character (',')
end
s_selectors.append (cs.item)
end
if not s_selectors.is_empty then
a_target.append (s_selectors)
a_target.append_character (' ')
a_target.append_character ('{')
a_target.append (c.item.style)
a_target.append_character ('}')
a_target.append_character ('%N')
end
end
end
end

View File

@@ -0,0 +1,24 @@
note
description: "Summary description for {CMS_CSS_SELECTOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_CSS_SELECTOR
create
make_from_string
feature {NONE} -- Initialization
make_from_string (s: READABLE_STRING_8)
do
string := s
end
feature -- Conversion
string: READABLE_STRING_8
end

View File

@@ -0,0 +1,393 @@
note
description: "Summary description for {CMS_CSS_STYLE}."
date: "$Date$"
revision: "$Revision$"
EIS: "name=CSS reference", "protocol=URI", "src=http://www.w3schools.com/cssref/"
class
CMS_CSS_STYLE
create
make,
make_from_string
feature {NONE} -- Initialization
make
do
create {ARRAYED_LIST [READABLE_STRING_8]} items.make (3)
end
make_from_string (s: READABLE_STRING_8)
do
items := s.split (';')
end
items: LIST [READABLE_STRING_8]
feature -- Change
put_key_value (k,v: READABLE_STRING_8)
do
items.force (k + ": " + v)
end
feature -- Property: colors
put_color (v: READABLE_STRING_8)
do
put_key_value ("color", v)
end
put_background (v: READABLE_STRING_8)
--| ex: #00ff00 url('smiley.gif') no-repeat fixed center;
do
put_key_value ("background", v)
end
put_background_color (v: READABLE_STRING_8)
do
put_key_value ("background-color", v)
end
feature -- Property: fonts
put_font (v: READABLE_STRING_8)
do
put_key_value ("font", v)
end
put_font_family (v: READABLE_STRING_8)
do
put_key_value ("font-family", v)
end
put_font_size (v: READABLE_STRING_8)
do
put_key_value ("font-size", v)
end
put_font_style (v: READABLE_STRING_8)
do
put_key_value ("font-style", v)
end
put_font_weight (v: READABLE_STRING_8)
do
put_key_value ("font-weight", v)
end
put_font_bold
do
put_font_weight ("bold")
end
put_font_italic
do
put_font_style ("italic")
end
put_text_decoration (v: READABLE_STRING_8)
do
put_key_value ("text-decoration", v)
end
put_text_decoration_none
do
put_text_decoration ("none")
end
put_text_decoration_underline
do
put_text_decoration ("underline")
end
put_text_decoration_strike
do
put_text_decoration ("strike")
end
put_text_align (v: READABLE_STRING_8)
do
put_key_value ("text-align", v)
end
put_white_space (v: READABLE_STRING_8)
--| normal Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary. This is default
--| nowrap Sequences of whitespace will collapse into a single whitespace. Text will never wrap to the next line. The text continues on the same line until a <br /> tag is encountered
--| pre Whitespace is preserved by the browser. Text will only wrap on line breaks Acts like the <pre> tag in HTML
--| pre-line Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary, and on line breaks
--| pre-wrap Whitespace is preserved by the browser. Text will wrap when necessary, and on line breaks
--| inherit Specifies that the value of the white-space property should be inherited from the parent element
do
put_key_value ("white-space", v)
end
put_white_space_nowrap
do
put_white_space ("nowrap")
end
put_white_space_pre
do
put_white_space ("pre")
end
feature -- Property: margin
put_margin (a_top, a_right, a_bottom, a_left: detachable READABLE_STRING_8)
local
v: STRING
do
create v.make (10)
if a_left /= Void then
v.append (a_left)
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_bottom /= Void then
v.prepend (a_bottom)
else
v.prepend_character ('0')
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_right /= Void then
v.prepend (a_right)
else
v.prepend_character ('0')
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_top /= Void then
v.prepend (a_top)
else
v.prepend_character ('0')
end
put_key_value ("margin", v)
end
put_margin_top (v: READABLE_STRING_8)
do
put_key_value ("margin-top", v)
end
put_margin_right (v: READABLE_STRING_8)
do
put_key_value ("margin-right", v)
end
put_margin_bottom (v: READABLE_STRING_8)
do
put_key_value ("margin-bottom", v)
end
put_margin_left (v: READABLE_STRING_8)
do
put_key_value ("margin-left", v)
end
feature -- Property: padding
put_padding (a_top, a_right, a_bottom, a_left: detachable READABLE_STRING_8)
local
v: STRING
do
create v.make (10)
if a_left /= Void then
v.append (a_left)
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_bottom /= Void then
v.prepend (a_bottom)
else
v.prepend_character ('0')
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_right /= Void then
v.prepend (a_right)
else
v.prepend_character ('0')
end
if not v.is_empty then
v.prepend_character (' ')
end
if a_top /= Void then
v.prepend (a_top)
else
v.prepend_character ('0')
end
put_key_value ("padding", v)
end
put_padding_top (v: READABLE_STRING_8)
do
put_key_value ("padding-top", v)
end
put_padding_right (v: READABLE_STRING_8)
do
put_key_value ("padding-right", v)
end
put_padding_bottom (v: READABLE_STRING_8)
do
put_key_value ("padding-bottom", v)
end
put_padding_left (v: READABLE_STRING_8)
do
put_key_value ("padding-left", v)
end
feature -- Properties: layout
put_width (v: READABLE_STRING_8)
do
put_key_value ("width", v)
end
put_height (v: READABLE_STRING_8)
do
put_key_value ("height", v)
end
put_z_index (v: READABLE_STRING_8)
do
put_key_value ("z-index", v)
end
feature -- Property: border
put_border (a_border: detachable READABLE_STRING_8; a_style: READABLE_STRING_8; a_size: READABLE_STRING_8; a_color: READABLE_STRING_8)
-- "solid 1px color"
require
a_border /= Void implies (a_border.same_string ("top") or a_border.same_string ("right") or a_border.same_string ("bottom") or a_border.same_string ("left"))
local
k: STRING
do
k := "border"
if a_border /= Void then
k.append_character ('-')
k.append (a_border)
end
put_key_value (k, a_style + " " + a_size + " " + a_color)
end
put_border_style (a_style: READABLE_STRING_8)
-- "solid 1px color"
do
put_key_value ("border-style", a_style)
end
put_border_style_none (a_style: READABLE_STRING_8)
-- "solid 1px color"
do
put_border_style ("none")
end
feature -- Property: display
put_display (v: READABLE_STRING_8)
do
put_key_value ("display", v)
end
put_display_none
do
put_display ("none")
end
put_display_block
do
put_display ("block")
end
put_display_inline
do
put_display ("inline")
end
put_display_inline_block
do
put_display ("inline-block")
end
put_list_style (v: READABLE_STRING_8)
--| ex: list-style:square url("sqpurple.gif");
do
put_key_value ("list-style", v)
end
put_list_style_type (v: READABLE_STRING_8)
--circle The marker is a circle
--decimal The marker is a number. This is default for <ol>
--decimal-leading-zero The marker is a number with leading zeros (01, 02, 03, etc.)
--disc The marker is a filled circle. This is default for <ul>
--lower-alpha The marker is lower-alpha (a, b, c, d, e, etc.)
--lower-greek The marker is lower-greek
--lower-latin The marker is lower-latin (a, b, c, d, e, etc.)
--lower-roman The marker is lower-roman (i, ii, iii, iv, v, etc.)
--none No marker is shown
--square The marker is a square
--upper-alpha The marker is upper-alpha (A, B, C, D, E, etc.)
--upper-latin The marker is upper-latin (A, B, C, D, E, etc.)
--upper-roman The marker is upper-roman (I, II, III, IV, V, etc.)
do
put_key_value ("list-style-type", v)
end
feature -- Property: float ...
put_float (v: READABLE_STRING_8)
do
put_key_value ("float", v)
end
put_clear (v: READABLE_STRING_8)
do
put_key_value ("clear", v)
end
feature -- Conversion
append_inline_to (s: STRING_8)
do
append_to (s, False)
end
append_text_to (s: STRING_8)
do
append_to (s, True)
end
append_to (s: STRING_8; a_multiline: BOOLEAN)
local
n: INTEGER
do
n := 0
across
items as c
loop
if n > 0 then
if a_multiline then
s.append_character ('%N')
else
s.append_character (' ')
end
end
s.append (c.item)
s.append_character (';')
n := n + 1
end
end
end

View File

@@ -0,0 +1,225 @@
note
description: "Summary description for {CMS_HTML_PAGE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_HTML_PAGE
create
make
feature {NONE} -- Initialization
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
end
feature -- Status
status_code: INTEGER
feature -- Header
header: HTTP_HEADER
feature -- Region
regions: HASH_TABLE [STRING_8, 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
html_head: STRING_8
local
t: like title
lines: like head_lines
do
t := title
lines := head_lines
if t /= Void or else lines.count > 0 then
create Result.make (50)
if t /= Void then
Result.append ("<title>" + t + "</title>%N")
end
Result.append_character ('%N')
across
lines as l
loop
Result.append (l.item)
Result.append_character ('%N')
end
else
create Result.make_empty
end
end
header_region: STRING_8
do
Result := region ("header")
end
content_region: STRING_8
do
Result := region ("content")
end
footer_region: STRING_8
do
Result := region ("content")
end
feature -- Element change
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
add_to_header_region (s: STRING)
do
add_to_region (s, "header")
end
add_to_content_region (s: STRING)
do
add_to_region (s, "content")
end
add_to_footer_region (s: STRING)
do
add_to_region (s, "footer")
end
set_region (s: STRING; k: STRING)
do
regions.force (s, k)
end
-- set_header_region (s: STRING)
-- do
-- set_region (s, "header")
-- end
-- set_content_region (s: STRING)
-- do
-- set_region (s, "content")
-- end
-- set_footer_region (s: STRING)
-- do
-- set_region (s, "footer")
-- end
feature -- Access
title: detachable STRING
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: HASH_TABLE [detachable ANY, STRING_8]
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
end

View File

@@ -0,0 +1,134 @@
note
description: "[
Summary description for CMS_SESSION_CONTROLER.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_SESSION_CONTROLER
inherit
ANY
WSF_SESSION_FACTORY [WSF_SESSION]
create
make
feature -- Initialization
make (req: WSF_REQUEST; a_mngr: like session_manager)
do
session_manager := a_mngr
initialize
create discarded_sessions.make
get_session (req)
end
initialize
do
end
feature -- Session access
session: WSF_SESSION
has_pending_session: BOOLEAN
discarded_sessions: LINKED_LIST [like session]
feature -- Session operation
session_commit (page: CMS_HTML_PAGE_RESPONSE; e: CMS_EXECUTION)
do
if has_pending_session then
session.apply_to (page.header, e.request, e.request.script_url ("/"))
end
session.commit
end
apply_sessions_to (h: HTTP_HEADER; req: WSF_REQUEST; a_path: detachable READABLE_STRING_8)
do
session.apply_to (h, req, a_path)
across
discarded_sessions as c
loop
c.item.apply_to (h, req, a_path)
end
end
start_session (req: WSF_REQUEST)
-- Start a new session
local
s: like session
do
close_session (req)
s := new_session (req, False, session_manager)
req.set_execution_variable (session_request_variable_name, s)
session := s
if s.is_pending then
has_pending_session := True
end
ensure
session_attached: session /= Void
end
get_session (req: WSF_REQUEST)
-- Get existing session, or start a new one
local
s: like session
do
if attached {like session} req.execution_variable (session_request_variable_name) as r_session then
session := r_session
else
s := new_session (req, True, session_manager)
-- create {CMS_SESSION} s.make (req, "_EWF_CMS_SESSID")
if s.is_pending then
has_pending_session := True
end
session := s
req.set_execution_variable (session_request_variable_name, s)
end
if session.expired then
start_session (req)
end
end
close_session (req: WSF_REQUEST)
-- Close `session' if any
do
if session.is_pending then
has_pending_session := has_pending_session or not discarded_sessions.is_empty
else
has_pending_session := True
discarded_sessions.extend (session)
end
session.destroy
end
feature -- Session internal
session_manager: WSF_SESSION_MANAGER
new_session (req: WSF_REQUEST; a_reuse: BOOLEAN; m: WSF_SESSION_MANAGER): like session
local
s: CMS_SESSION
dt: DATE_TIME
do
if a_reuse then
create s.make (req, session_id_name, m)
else
create s.make_new (session_id_name, m)
create dt.make_now_utc
dt.day_add (31)
s.set_expiration (dt)
end
Result := s
end
session_request_variable_name: STRING = "_EWF_CMS_SESSION_"
session_id_name: STRING = "_EWF_CMS_SESSID"
end

View File

@@ -0,0 +1,160 @@
note
description: "Summary description for {CMS_USER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_USER
inherit
DEBUG_OUTPUT
create
make_new,
make
feature {NONE} -- Initialization
make (a_id: like id; n: like name; dt: like creation_date)
require
a_id > 0
do
id := a_id
creation_date := dt
name := n
ensure
valid_password: password = Void
end
make_new (n: like name)
do
name := n
create creation_date.make_now_utc
end
feature -- Access
is_admin: BOOLEAN
do
Result := id = 1
end
id: INTEGER
name: STRING_8
password: detachable READABLE_STRING_32
email: detachable READABLE_STRING_8
profile: detachable CMS_USER_PROFILE
creation_date: DATE_TIME
last_login_date: detachable DATE_TIME
data: detachable HASH_TABLE [detachable ANY, STRING]
data_item (k: STRING): detachable ANY
do
if attached data as l_data then
Result := l_data.item (k)
end
end
feature -- Status report
has_id: BOOLEAN
do
Result := id > 0
end
has_email: BOOLEAN
do
Result := attached email as e and then not e.is_empty
end
debug_output: STRING
do
Result := name
end
same_as (u: detachable CMS_USER): BOOLEAN
do
Result := u /= Void and then id = u.id
end
feature -- Element change
set_id (a_id: like id)
do
id := a_id
end
set_password (p: like password)
do
password := p
end
set_email (m: like email)
do
email := m
end
set_profile (prof: like profile)
do
profile := prof
end
set_data_item (k: READABLE_STRING_8; d: like data_item)
local
l_data: like data
do
l_data := data
if l_data = Void then
create l_data.make (1)
data := l_data
end
l_data.force (d, k)
end
remove_data_item (k: READABLE_STRING_8)
do
if attached data as l_data then
l_data.remove (k)
end
end
set_profile_item (k: READABLE_STRING_8; v: READABLE_STRING_8)
local
prof: like profile
do
prof := profile
if prof = Void then
create prof.make
profile := prof
end
prof.force (v, k)
end
set_last_login_date (dt: like last_login_date)
do
last_login_date := dt
end
set_last_login_date_now
do
set_last_login_date (create {DATE_TIME}.make_now_utc)
end
feature {CMS_STORAGE} -- Security
encoded_password: detachable READABLE_STRING_8
set_encoded_password (p: like encoded_password)
do
encoded_password := p
end
end

View File

@@ -0,0 +1,51 @@
note
description: "Summary description for {CMS_USER_PROFILE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_USER_PROFILE
inherit
TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_8]
create
make
feature {NONE} -- Initialization
make
do
create items.make (0)
end
feature -- Access
item (k: READABLE_STRING_8): detachable READABLE_STRING_8
do
Result := items.item (k.as_string_8)
end
feature -- Change
force (v: READABLE_STRING_8; k: READABLE_STRING_8)
do
items.force (v, k.as_string_8)
end
feature -- Access
new_cursor: TABLE_ITERATION_CURSOR [READABLE_STRING_8, READABLE_STRING_8]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature {NONE} -- Implementation
items: HASH_TABLE [READABLE_STRING_8, STRING_8]
invariant
end

View File

@@ -0,0 +1,32 @@
note
description: "Summary description for {CMS_BLOCK}."
author: ""
date: "$Date$"
revision: "$Revision$"
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
invariant
end

View File

@@ -0,0 +1,46 @@
note
description: "Summary description for {CMS_CONTENT_BLOCK}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_CONTENT_BLOCK
inherit
CMS_BLOCK
create
make
feature {NONE} -- Initialization
make (a_name: like name; a_title: like title; a_body: like body; a_format: like format)
do
is_enabled := True
name := a_name
title := a_title
body := a_body
format := a_format
end
feature -- Access
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
body: READABLE_STRING_8
format: CMS_FORMAT
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := format.to_html (body)
end
invariant
end

View File

@@ -0,0 +1,60 @@
note
description: "Summary description for {CMS_CONTENT_TYPE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_CONTENT_TYPE
feature -- Access
name: READABLE_STRING_8
-- Internal name
deferred
end
title: READABLE_STRING_8
deferred
end
description: detachable READABLE_STRING_8
-- Optional description
deferred
end
available_formats: LIST [CMS_FORMAT]
deferred
end
feature -- Factory
fill_edit_form (f: CMS_FORM; a_node: detachable CMS_NODE)
-- Fill the edit form `f'
deferred
end
change_node (a_execution: CMS_EXECUTION; a_form_data: CMS_FORM_DATA; a_node: like new_node)
-- Apply data from `a_form_data' to a_node
require
a_node.has_id
deferred
end
new_node (a_execution: CMS_EXECUTION; a_form_data: CMS_FORM_DATA; a_node: detachable like new_node): CMS_NODE
-- New content created with `a_form_data'
deferred
ensure
a_node /= Void implies a_node = Result
end
feature {NONE} -- Implementation: helper
formats: CMS_FORMATS
once
create Result
end
invariant
end

View File

@@ -0,0 +1,45 @@
note
description: "Summary description for {CMS_MENU_BLOCK}."
author: ""
date: "$Date$"
revision: "$Revision$"
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
invariant
end

View File

@@ -0,0 +1,101 @@
note
description: "Summary description for {WSF_CMS_NODE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_NODE
feature -- Access
id: INTEGER
-- Unique identifier of Current.
title: detachable READABLE_STRING_32
-- Associated title (optional).
deferred
end
body: detachable READABLE_STRING_8
-- Body of Current.
deferred
end
format: CMS_FORMAT
-- Format associated with `body'
deferred
end
content_type_name: STRING
-- Associated content type name
deferred
end
feature -- status report
has_id: BOOLEAN
do
Result := id > 0
end
feature -- Access: status
author: detachable CMS_USER
creation_date: DATE_TIME
modification_date: DATE_TIME
feature -- Change
set_id (a_id: like id)
require
not has_id
do
id := a_id
end
set_author (u: like author)
do
author := u
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
local
d: STRING
do
Result := "<div class=%"node " + content_type_name + "%" id=%"nid-" + id.out + "%">"
if attached title as l_title then
Result.append ("<div class=%"title%">" + a_theme.node_link (Current) + "</div>")
end
create d.make_empty
if attached author as u then
d.append ("by " + a_theme.user_link (u) + " ")
end
if attached modification_date as dt then
d.append ("last modified: " + dt.year.out + "/" + dt.month.out + "/" + dt.day.out + "")
end
if not d.is_empty then
Result.append ("<div class=%"description%">")
Result.append (d)
Result.append ("</div>")
end
if attached body as b then
Result.append ("<div class=%"inner%">")
Result.append (format.to_html (b))
Result.append ("</div>")
end
Result.append ("</div>")
end
feature {NONE} -- Implementation: helper
formats: CMS_FORMATS
once
create Result
end
end

View File

@@ -0,0 +1,44 @@
note
description : "[
Filtered html format
]"
date : "$Date$"
revision : "$Revision$"
class
CMS_FILTERED_HTML_FORMAT
inherit
CMS_FORMAT
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create filters.make (3)
filters.force (create {CMS_URL_FILTER})
filters.force (create {CMS_HTML_FILTER})
filters.force (create {CMS_LINE_BREAK_CONVERTER_FILTER})
-- help := "<ul><li>Web page addresses and e-mail addresses turn into links automatically.</li><li>Allowed HTML tags: "
-- across
-- allowed_html_tags as c
-- loop
-- help.append ("&lt;" + c.item + "&gt; ")
-- end
-- help.append ("</li><li>Lines and paragraphs break automatically.</li></ul>")
end
feature -- Access
name: STRING = "filtered_html"
title: STRING_8 = "Filtered HTML"
filters: ARRAYED_LIST [CMS_FILTER]
end

View File

@@ -0,0 +1,46 @@
note
description: "Summary description for {WSF_CMS_FORMAT}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FORMAT
feature -- Access
name: STRING
deferred
end
title: READABLE_STRING_8
deferred
end
help: STRING
do
create Result.make (0)
across
filters as c
loop
if attached c.item.help as h and then not h.is_empty then
Result.append ("<li>" + h + "</li>")
end
end
end
filters: LIST [CMS_FILTER]
deferred
end
to_html (a_text: READABLE_STRING_8): STRING_8
do
create Result.make_from_string (a_text)
across
filters as c
loop
c.item.filter (Result)
end
end
end

View File

@@ -0,0 +1,54 @@
note
description: "Summary description for {CMS_FORMATS}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORMATS
feature -- Access
format (a_name: like {CMS_FORMAT}.name): detachable CMS_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 [CMS_FORMAT]
once
create {ARRAYED_LIST [CMS_FORMAT]} Result.make (3)
Result.force (plain_text)
Result.force (full_html)
Result.force (filtered_html)
end
default_format: CMS_FORMAT
do
Result := plain_text --FIXME
end
plain_text: CMS_PLAIN_TEXT_FORMAT
once
create Result
end
full_html: CMS_FULL_HTML_FORMAT
once
create Result
end
filtered_html: CMS_FILTERED_HTML_FORMAT
once
create Result
end
end

View File

@@ -0,0 +1,35 @@
note
description : "[
Full html format
]"
date : "$Date$"
revision : "$Revision$"
class
CMS_FULL_HTML_FORMAT
inherit
CMS_FORMAT
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create filters.make (2)
filters.force (create {CMS_URL_FILTER})
filters.force (create {CMS_LINE_BREAK_CONVERTER_FILTER})
end
feature -- Access
name: STRING = "full_html"
title: STRING_8 = "Full HTML"
filters: ARRAYED_LIST [CMS_FILTER]
end

View File

@@ -0,0 +1,49 @@
note
description : "[
Plain Text format
]"
date : "$Date$"
revision : "$Revision$"
class
CMS_PLAIN_TEXT_FORMAT
inherit
CMS_FORMAT
redefine
default_create,
help
end
feature {NONE} -- Initialization
default_create
do
Precursor
create filters.make (2)
filters.force (create {CMS_HTML_TO_TEXT_FILTER})
filters.force (create {CMS_LINE_BREAK_CONVERTER_FILTER})
end
feature -- Access
name: STRING = "plain_text"
title: STRING_8 = "Plain text"
help: STRING
do
Result := "<li>No HTML tags allowed.</li>"
Result.append (Precursor)
end
-- <ul>
-- <li>No HTML tags allowed.</li>
-- <li>Web page addresses and e-mail addresses turn into links automatically.</li>
-- <li>Lines and paragraphs break automatically.</li>
-- </ul>
-- ]"
filters: ARRAYED_LIST [CMS_FILTER]
end

View File

@@ -0,0 +1,35 @@
note
description: "Summary description for {CMS_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FILTER
feature -- Access
name: READABLE_STRING_8
deferred
end
title: READABLE_STRING_8
deferred
end
description: READABLE_STRING_8
deferred
end
help: READABLE_STRING_8
do
Result := description
end
feature -- Conversion
filter (s: STRING_8)
deferred
end
end

View File

@@ -0,0 +1,126 @@
note
description: "Summary description for {CMS_HTML_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_HTML_FILTER
inherit
CMS_FILTER
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
allowed_html_tags := <<"a", "em", "strong", "cite", "blockquote", "code", "ul", "ol", "li", "dl">>
description := "Allowed HTML tags: "
across
allowed_html_tags as c
loop
description.append ("&lt;" + c.item + "&gt; ")
end
end
feature -- Access
name: STRING_8 = "html_filter"
title: STRING_8 = "HTML filter"
description: STRING_8
allowed_html_tags: ITERABLE [READABLE_STRING_8]
feature -- Conversion
filter (a_text: STRING_8)
local
l_new: STRING_8
i: INTEGER
n: INTEGER
in_tag: BOOLEAN
p1, p2: INTEGER
do
create l_new.make (a_text.count)
from
p1 := 1
i := a_text.index_of ('<', 1)
if i > 0 then
l_new.append (a_text.substring (1, i - 1))
end
n := a_text.count
until
i = 0 or i > n
loop
if a_text[i] = '<' then
in_tag := True
p1 := i
p2 := a_text.index_of ('>', i + 1)
if p2 = 0 then
-- next '<'
i := a_text.index_of ('<', i + 1)
if i > 0 then
l_new.append (a_text.substring (p1, i - 1))
end
else
if is_authorized (a_text.substring (p1, p2)) then
l_new.append (a_text.substring (p1, p2))
i := a_text.index_of ('<', p2 + 1)
else
i := a_text.index_of ('<', p2 + 1)
end
if i > 0 then
l_new.append (a_text.substring (p2 + 1, i - 1))
end
end
else
i := i + 1
end
end
l_new.append (a_text.substring (p1, n))
a_text.wipe_out
a_text.append (l_new)
end
is_authorized (s: READABLE_STRING_8): BOOLEAN
-- Is `s' authorized?
--| `s' has either "<....>" or "<..../>" or "</.....>"
local
l_tagname: detachable STRING
i,n,p1: INTEGER
do
-- create l_tagname.make_empty
from
i := 2 -- skip first '<'
n := s.count
until
i > n or l_tagname /= Void
loop
if p1 > 0 then
if s[i].is_space or s[i] = '/' or s[i] = '>' then
l_tagname := s.substring (p1, i - 1)
end
else
if s[i].is_space or s[i] = '/' then
else
p1 := i
end
end
i := i + 1
end
if l_tagname /= Void then
l_tagname.to_lower
Result := across allowed_html_tags as c some c.item.same_string (l_tagname) end
else
Result := True
end
end
end

View File

@@ -0,0 +1,34 @@
note
description: "Summary description for {CMS_HTML_TO_TEXT_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_HTML_TO_TEXT_FILTER
inherit
CMS_FILTER
feature -- Access
name: STRING_8 = "html_to_text"
title: STRING_8 = "HTML to text"
description: STRING_8 = "Replaces HTML tags and entities with plain text formatting, moving links at the end. This filter is just for text messages and it isn't safe for rendering content on a web page."
feature -- Conversion
filter (a_text: STRING_8)
local
enc: HTML_ENCODER
s: STRING_8
do
create enc
s := enc.encoded_string (a_text)
a_text.wipe_out
a_text.append (s)
end
end

View File

@@ -0,0 +1,34 @@
note
description: "Summary description for {CMS_HTML_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_LINE_BREAK_CONVERTER_FILTER
inherit
CMS_FILTER
redefine
help
end
feature -- Access
name: STRING_8 = "line_break_converter"
title: STRING_8 = "Line break converter"
help: STRING = "Lines and paragraphs break automatically"
description: STRING_8 = "Converts line breaks into HTML (i.e. &lt;br&gt; and &lt;p&gt; tags)."
feature -- Conversion
filter (a_text: STRING_8)
do
a_text.replace_substring_all ("%N", "<br/>%N")
-- FIXME jfiat [2012/09/12] :also use <p> ...
end
end

View File

@@ -0,0 +1,77 @@
note
description: "Summary description for {CMS_NO_HTML_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_NO_HTML_FILTER
inherit
CMS_FILTER
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
end
feature -- Access
name: STRING_8 = "no_html_filter"
title: STRING_8 = "No HTML filter"
description: STRING_8 = "HTML tags removed! "
feature -- Conversion
filter (a_text: STRING_8)
local
l_new: STRING_8
i: INTEGER
n: INTEGER
in_tag: BOOLEAN
p1, p2: INTEGER
do
create l_new.make (a_text.count)
from
p1 := 1
i := a_text.index_of ('<', 1)
if i > 0 then
l_new.append (a_text.substring (1, i - 1))
end
n := a_text.count
until
i = 0 or i > n
loop
if a_text[i] = '<' then
in_tag := True
p1 := i
p2 := a_text.index_of ('>', i + 1)
if p2 = 0 then
-- next '<'
i := a_text.index_of ('<', i + 1)
if i > 0 then
l_new.append (a_text.substring (p1, i - 1))
end
else
i := a_text.index_of ('<', p2 + 1)
if i > 0 then
l_new.append (a_text.substring (p2 + 1, i - 1))
end
end
else
i := i + 1
end
end
l_new.append (a_text.substring (p1, n))
a_text.wipe_out
a_text.append (l_new)
end
end

View File

@@ -0,0 +1,33 @@
note
description: "Summary description for {CMS_URL_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_URL_FILTER
inherit
CMS_FILTER
redefine
help
end
feature -- Access
name: STRING_8 = "url"
title: STRING_8 = "URL filter"
description: STRING_8 = "Turns web and e-mail addresses into clickable links."
help: STRING = "Web page addresses and e-mail addresses turn into links automatically."
feature -- Conversion
filter (a_text: STRING_8)
do
--| FIXME jfiat [2012/09/12] : todo
end
end

View File

@@ -0,0 +1,181 @@
note
description: "Summary description for {CMS_FORM}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM
inherit
ITERABLE [CMS_FORM_ITEM]
create
make
feature {NONE} -- Initialization
make (a_action: READABLE_STRING_8; a_id: READABLE_STRING_8)
do
action := a_action
id := a_id
create html_classes.make (2)
create items.make (10)
set_method_post
end
feature -- Access
action: READABLE_STRING_8
-- URL for the web form
id: READABLE_STRING_8
-- Id of the form
count: INTEGER
do
Result := items.count
end
method: READABLE_STRING_8
-- Form's method
--| GET or POST
feature -- Validation
validation_action: detachable PROCEDURE [ANY, TUPLE [CMS_FORM_DATA]]
-- Procedure to validate the data
-- report error if not valid
-- submit_callbacks_actions: HASH_TABLE [PROCEDURE [ANY, TUPLE [CMS_FORM_DATA]], STRING]
-- -- Submit callbacks indexed by submit names
feature -- Element change
set_method_get
do
method := "GET"
end
set_method_post
do
method := "POST"
end
set_validation_action (act: like validation_action)
do
validation_action := act
end
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_FORM_ITEM]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature -- Optional
html_classes: ARRAYED_LIST [STRING_8]
feature -- Items
has_field (a_name: READABLE_STRING_GENERAL): BOOLEAN
do
Result := across items as i some attached {CMS_FORM_FIELD} i.item as l_field and then l_field.name.same_string_general (a_name) end
end
-- items_by_name (a_name: READABLE_STRING_GENERAL): detachable LIST [CMS_FORM_ITEM]
-- local
-- res: detachable ARRAYED_LIST [CMS_FORM_ITEM]
-- do
-- across
-- items as c
-- loop
-- if c.item.name.same_string_general (a_name) then
-- if res = Void then
-- create res.make (1)
-- end
-- res.force (c.item)
-- end
-- end
-- Result := res
-- end
fields_by_name (a_name: READABLE_STRING_GENERAL): detachable LIST [CMS_FORM_FIELD]
local
res: detachable ARRAYED_LIST [CMS_FORM_FIELD]
do
across
items as c
loop
if
attached {CMS_FORM_FIELD} c.item as l_field and then
l_field.name.same_string_general (a_name)
then
if res = Void then
create res.make (1)
end
res.force (l_field)
end
end
Result := res
end
extend (i: CMS_FORM_ITEM)
local
n: READABLE_STRING_8
do
if attached {CMS_FORM_FIELD} i as l_field then
n := l_field.name
if n.is_empty then
n := (items.count + 1).out
l_field.update_name (n)
end
end
items.force (i)
end
extend_text (t: READABLE_STRING_8)
do
extend (create {CMS_FORM_RAW_TEXT}.make (t))
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
local
s: STRING
do
Result := "<form action=%""+ action +"%" id=%""+ id +"%" method=%""+ method +"%" "
if not html_classes.is_empty then
create s.make_empty
across
html_classes as cl
loop
if not s.is_empty then
s.extend (' ')
end
s.append (cl.item)
end
Result.append (" class=%"" + s + "%" ")
end
Result.append (">%N")
across
items as c
loop
Result.append (c.item.to_html (a_theme))
end
Result.append ("</form>%N")
end
feature {NONE} -- Implementation
items: ARRAYED_LIST [CMS_FORM_ITEM]
-- name => item
invariant
end

View File

@@ -0,0 +1,20 @@
note
description: "Summary description for {CMS_FORM_BUTTON_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_BUTTON_INPUT
inherit
CMS_FORM_INPUT
create
make
feature -- Access
input_type: STRING = "button"
end

View File

@@ -0,0 +1,81 @@
note
description: "Summary description for {CMS_FORM_CHECKBOX_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_CHECKBOX_INPUT
inherit
CMS_FORM_INPUT
rename
default_value as value
redefine
specific_input_attributes_string,
child_to_html
end
CMS_FORM_SELECTABLE_ITEM
rename
is_selected as checked,
set_is_selected as set_checked
end
create
make,
make_with_text
feature -- Access
checked: BOOLEAN
-- Current <input> element should be preselected when the page loads
input_type: STRING = "checkbox"
text: detachable READABLE_STRING_32
feature -- Status report
is_same_value (v: READABLE_STRING_32): BOOLEAN
do
Result := attached value as l_value and then v.same_string (l_value)
end
feature -- Change
set_text (t: detachable READABLE_STRING_32)
do
text := t
end
set_checked (b: like checked)
do
checked := b
end
feature {NONE} -- Implementation
child_to_html (a_theme: CMS_THEME): detachable READABLE_STRING_8
-- Specific child element if any.
--| To redefine if needed
do
if attached text as t then
Result := a_theme.html_encoded (t)
elseif attached value as v then
Result := a_theme.html_encoded (v)
end
end
specific_input_attributes_string: detachable STRING_8
-- Specific input attributes if any.
-- To redefine if needed
do
if checked then
Result := "checked=%"checked%""
end
end
invariant
end

View File

@@ -0,0 +1,195 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_FORM_DATA
inherit
TABLE_ITERABLE [detachable WSF_VALUE, READABLE_STRING_8]
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; a_form: CMS_FORM)
-- Initialize `Current'.
do
form := a_form
create items.make (a_form.count)
get_items (req)
validate
end
feature -- Access
form: CMS_FORM
feature -- Status
is_valid: BOOLEAN
do
Result := errors = Void
end
feature -- Access
item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
do
Result := items.item (a_name.as_string_8)
end
string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
do
if attached {WSF_STRING} item (a_name) as s then
Result := s.value
end
end
integer_item (a_name: READABLE_STRING_GENERAL): INTEGER
do
if attached {WSF_STRING} item (a_name) as s and then s.is_integer then
Result := s.integer_value
end
end
new_cursor: TABLE_ITERATION_CURSOR [detachable WSF_VALUE, READABLE_STRING_8]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature -- Basic operation
validate
do
across
form as f
loop
if attached {CMS_FORM_FIELD} f.item as l_field then
l_field.validate (Current)
end
end
if attached form.validation_action as act then
act.call ([Current])
end
end
set_fields_invalid (b: BOOLEAN; a_name: READABLE_STRING_GENERAL)
do
if attached form.fields_by_name (a_name) as lst then
across
lst as i
loop
i.item.set_is_invalid (b)
end
end
end
apply_to_associated_form
do
if attached errors as errs then
across
errs as e
loop
if attached e.item as err then
if attached err.field as e_field then
set_fields_invalid (True, e_field.name)
end
end
end
end
across
items as c
loop
across
form as i
loop
if attached {CMS_FORM_FIELD} i.item as l_field then
if not attached {CMS_FORM_SUBMIT_INPUT} l_field then
if l_field.name.same_string (c.key) then
l_field.set_value (c.item)
end
end
end
end
end
end
feature -- Change
report_error (a_msg: READABLE_STRING_8)
do
add_error (Void, a_msg)
ensure
is_invalid: not is_valid
end
report_invalid_field (a_field_name: READABLE_STRING_8; a_msg: READABLE_STRING_8)
require
has_field: form.has_field (a_field_name)
do
if attached form.fields_by_name (a_field_name) as lst then
across
lst as c
loop
add_error (c.item, a_msg)
end
end
ensure
is_invalid: not is_valid
end
feature {NONE} -- Implementation
get_items (req: WSF_REQUEST)
do
get_form_items (req, form)
end
get_form_items (req: WSF_REQUEST; lst: ITERABLE [CMS_FORM_ITEM])
local
n: READABLE_STRING_8
v: detachable WSF_VALUE
do
across
lst as c
loop
if attached {CMS_FORM_FIELD} c.item as l_field then
n := l_field.name
v := req.form_parameter (n)
if l_field.is_required and (v = Void or else v.is_empty) then
add_error (l_field, "Field %"<em>" + l_field.name + "</em>%" is required")
else
items.force (v, n)
end
elseif attached {CMS_FORM_FIELD_SET} c.item as l_fieldset then
get_form_items (req, l_fieldset)
end
end
end
add_error (a_field: detachable CMS_FORM_FIELD; a_msg: detachable READABLE_STRING_8)
local
err: like errors
do
err := errors
if err = Void then
create err.make (1)
errors := err
end
err.force ([a_field, a_msg])
end
items: HASH_TABLE [detachable WSF_VALUE, READABLE_STRING_8]
feature -- Reports
errors: detachable ARRAYED_LIST [TUPLE [field: detachable CMS_FORM_FIELD; message: detachable READABLE_STRING_8]]
invariant
end

View File

@@ -0,0 +1,65 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_FORM_DIV
inherit
CMS_FORM_ITEM
ITERABLE [CMS_FORM_ITEM]
WITH_CSS_ID
create
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
do
create items.make (0)
end
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_FORM_ITEM]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature -- Change
extend (i: CMS_FORM_ITEM)
do
items.force (i)
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<div"
append_css_class_to (Result, Void)
append_css_id_to (Result)
append_css_style_to (Result)
Result.append (">%N")
across
items as c
loop
Result.append (c.item.to_html (a_theme))
end
Result.append ("%N</div>%N")
end
feature {NONE} -- Implementation
items: ARRAYED_LIST [CMS_FORM_ITEM]
end

View File

@@ -0,0 +1,146 @@
note
description: "Summary description for {CMS_FORM_ITEM}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FORM_FIELD
inherit
CMS_FORM_ITEM
WITH_CSS_ID
DEBUG_OUTPUT
feature -- Access
name: READABLE_STRING_8
label: detachable READABLE_STRING_8
description: detachable READABLE_STRING_8
is_required: BOOLEAN
is_invalid: BOOLEAN
is_readonly: BOOLEAN
is_description_collapsible: BOOLEAN
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := name + " {" + generator + "}"
end
feature -- Validation
validation_action: detachable PROCEDURE [ANY, TUPLE [CMS_FORM_DATA]]
-- Function returning True if valid, otherwise False
validate (fd: CMS_FORM_DATA)
do
if attached validation_action as act then
act.call ([fd])
end
end
feature -- Element change
update_name (a_name: like name)
require
name.is_empty
do
name := a_name
end
set_is_required (b: BOOLEAN)
do
is_required := b
end
set_is_readonly (b: BOOLEAN)
do
is_readonly := b
end
set_label (lab: like label)
do
label := lab
end
set_description (t: like description)
do
description := t
end
set_validation_action (act: like validation_action)
do
validation_action := act
end
set_is_invalid (b: BOOLEAN)
do
is_invalid := b
end
set_value (v: detachable WSF_VALUE)
-- Set value `v' if applicable to Current
deferred
end
set_description_collapsible (b: BOOLEAN)
-- Set `is_description_collapsible' to `b'
do
is_description_collapsible := b
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
local
l_class_items: detachable ARRAYED_LIST [READABLE_STRING_8]
do
create l_class_items.make (2)
if is_required then
l_class_items.extend ("required")
end
if is_invalid then
l_class_items.extend ("error")
end
if l_class_items.is_empty then
l_class_items := Void
end
create Result.make_from_string ("<div")
append_css_class_to (Result, l_class_items)
Result.append_character ('>')
if attached label as lab then
Result.append ("<strong><label for=%"" + name + "%">" + lab + "</label></strong>")
if is_required then
Result.append (" (<em>required</em>)")
end
Result.append ("<br/>%N")
end
Result.append (item_to_html (a_theme))
if attached description as desc then
if is_description_collapsible then
Result.append ("<div class=%"description collapsible%"><div>Description ...</div><div>" + desc + "</div></div>")
else
Result.append ("<div class=%"description%">" + desc + "</div>")
end
end
Result.append ("</div>")
end
item_to_html (a_theme: CMS_THEME): STRING_8
deferred
end
end

View File

@@ -0,0 +1,77 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_FORM_FIELD_SET
inherit
CMS_FORM_ITEM
ITERABLE [CMS_FORM_ITEM]
WITH_CSS_ID
create
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
do
create items.make (0)
end
feature -- Access
legend: detachable READABLE_STRING_8
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_FORM_ITEM]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature -- Change
set_legend (v: like legend)
do
legend := v
end
extend (i: CMS_FORM_ITEM)
do
items.force (i)
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<fieldset"
append_css_class_to (Result, Void)
append_css_id_to (Result)
append_css_style_to (Result)
Result.append (">%N")
if attached legend as leg then
Result.append ("<legend>" + leg + "</legend>%N")
end
across
items as c
loop
Result.append (c.item.to_html (a_theme))
end
Result.append ("%N</fieldset>%N")
end
feature {NONE} -- Implementation
items: ARRAYED_LIST [CMS_FORM_ITEM]
end

View File

@@ -0,0 +1,46 @@
note
description: "Summary description for {CMS_FORM_FILE_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_FILE_INPUT
inherit
CMS_FORM_INPUT
redefine
specific_input_attributes_string
end
create
make
feature -- Access
input_type: STRING = "file"
accepted_types: detachable READABLE_STRING_8
-- Types of files that the server accepts
feature -- Change
set_accepted_types (v: like accepted_types)
do
accepted_types := v
end
feature {NONE} -- Implementation
specific_input_attributes_string: detachable STRING_8
-- Specific input attributes if any.
-- To redefine if needed
do
if attached accepted_types as l_accepted_types then
Result := " accept=%"" + l_accepted_types + "%""
end
end
invariant
end

View File

@@ -0,0 +1,37 @@
note
description: "Summary description for {CMS_FORM_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_HIDDEN_INPUT
inherit
CMS_FORM_INPUT
redefine
input_type,
item_to_html
end
create
make,
make_with_text
feature -- Access
input_type: STRING
once
Result := "hidden"
end
feature -- Conversion
item_to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<div style=%"display:none%">"
Result.append (Precursor (a_theme))
Result.append ("</div>")
end
end

View File

@@ -0,0 +1,58 @@
note
description: "Summary description for {CMS_FORM_IMAGE_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_IMAGE_INPUT
inherit
CMS_FORM_INPUT
redefine
specific_input_attributes_string
end
create
make
feature -- Access
input_type: STRING = "image"
src: detachable READABLE_STRING_8
-- Specifies the URL of the image to use as a submit button
alt: detachable READABLE_STRING_8
-- Alternate text for an image.
feature -- Change
set_src (v: like src)
do
src := v
end
set_alt (v: like alt)
do
alt := v
end
feature {NONE} -- Implementation
specific_input_attributes_string: detachable STRING_8
-- Specific input attributes if any.
-- To redefine if needed
do
create Result.make_empty
if attached src as l_src then
Result.append (" src=%"" + l_src + "%"")
end
if attached alt as l_alt then
Result.append (" alt=%"" + l_alt + "%"")
end
end
invariant
end

View File

@@ -0,0 +1,131 @@
note
description: "Summary description for {CMS_FORM_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FORM_INPUT
inherit
CMS_FORM_FIELD
feature {NONE} -- Initialization
make (a_name: like name)
do
name := a_name
end
make_with_text (a_name: like name; a_text: READABLE_STRING_32)
do
make (a_name)
set_text_value (a_text)
end
feature -- Access
default_value: detachable READABLE_STRING_32
size: INTEGER
-- Width, in characters, of an <input> element.
maxlength: INTEGER
-- Maximum number of characters allowed in an <input> element.
disabled: BOOLEAN
-- Current <input> element should be disabled?
input_type: STRING
deferred
end
feature -- Element change
set_text_value (s: detachable READABLE_STRING_32)
do
set_default_value (s)
end
set_size (i: like size)
do
size := i
end
set_maxlength (i: like maxlength)
do
maxlength := i
end
set_disabled (b: like disabled)
do
disabled := b
end
set_value (v: detachable WSF_VALUE)
do
if attached {WSF_STRING} v as s then
set_text_value (s.value)
else
set_text_value (Void)
end
end
set_default_value (v: like default_value)
do
default_value := v
end
feature -- Conversion
item_to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<input type=%""+ input_type +"%" name=%""+ name +"%""
append_css_class_to (Result, Void)
append_css_id_to (Result)
append_css_style_to (Result)
if is_readonly then
Result.append (" readonly=%"readonly%"")
end
if attached default_value as dft then
Result.append (" value=%"" + a_theme.html_encoded (dft) + "%"")
end
if disabled then
Result.append (" disabled=%"disabled%"")
end
if size > 0 then
Result.append (" size=%"" + size.out + "%"")
end
if maxlength > 0 then
Result.append (" maxlength=%"" + maxlength.out + "%"")
end
if attached specific_input_attributes_string as s then
Result.append_character (' ')
Result.append (s)
end
if attached child_to_html (a_theme) as s then
Result.append (">")
Result.append (s)
Result.append ("</input>")
else
Result.append ("/>")
end
end
feature {NONE} -- Implementation
child_to_html (a_theme: CMS_THEME): detachable READABLE_STRING_8
-- Specific child element if any.
--| To redefine if needed
do
end
specific_input_attributes_string: detachable STRING_8
-- Specific input attributes if any.
--| To redefine if needed
do
end
end

View File

@@ -0,0 +1,21 @@
note
description: "Summary description for {CMS_FORM_ITEM}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FORM_ITEM
inherit
WITH_CSS_CLASS
WITH_CSS_STYLE
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
deferred
end
end

View File

@@ -0,0 +1,27 @@
note
description: "Summary description for {CMS_FORM_PASSWORD_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_PASSWORD_INPUT
inherit
CMS_FORM_INPUT
redefine
input_type
end
create
make,
make_with_text
feature -- Access
input_type: STRING
once
Result := "password"
end
end

View File

@@ -0,0 +1,61 @@
note
description: "Summary description for {CMS_FORM_RADIO_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_RADIO_INPUT
inherit
CMS_FORM_INPUT
rename
default_value as value
redefine
specific_input_attributes_string
end
CMS_FORM_SELECTABLE_ITEM
rename
is_selected as checked,
set_is_selected as set_checked
end
create
make
feature -- Access
checked: BOOLEAN
-- Current <input> element should be preselected when the page loads
input_type: STRING = "radio"
feature -- Status report
is_same_value (v: READABLE_STRING_32): BOOLEAN
do
Result := attached value as l_value and then v.same_string (l_value)
end
feature -- Change
set_checked (b: like checked)
do
checked := b
end
feature {NONE} -- Implementation
specific_input_attributes_string: detachable STRING_8
-- Specific input attributes if any.
-- To redefine if needed
do
if checked then
Result := "checked=%"checked%""
end
end
invariant
end

View File

@@ -0,0 +1,49 @@
note
description: "Summary description for {CMS_FORM_RAW_TEXT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_RAW_TEXT
inherit
CMS_FORM_ITEM
redefine
to_html
end
create
make
feature {NONE} -- Initialization
make (a_text: like text)
do
text := a_text
end
feature -- Access
text: READABLE_STRING_8
feature -- Element change
set_value (v: detachable WSF_VALUE)
do
-- Not applicable
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := item_to_html (a_theme)
end
item_to_html (a_theme: CMS_THEME): STRING_8
do
Result := text
end
end

View File

@@ -0,0 +1,20 @@
note
description: "Summary description for {CMS_FORM_RESET_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_RESET_INPUT
inherit
CMS_FORM_INPUT
create
make
feature -- Access
input_type: STRING = "reset"
end

View File

@@ -0,0 +1,125 @@
note
description: "Summary description for {CMS_FORM_SELECT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_SELECT
inherit
CMS_FORM_FIELD
CMS_FORM_UTILITY
create
make
feature {NONE} -- Initialization
make (a_name: like name)
do
name := a_name
create options.make (0)
end
feature -- Access
options: ARRAYED_LIST [CMS_FORM_SELECT_OPTION]
feature -- Element change
set_text_by_value (a_text: detachable READABLE_STRING_GENERAL)
local
opt: CMS_FORM_SELECT_OPTION
l_found: BOOLEAN
v: READABLE_STRING_8
do
if a_text /= Void then
v := html_encoded_string (a_text.to_string_32)
across
options as o
loop
if o.item.is_same_value (v) then
l_found := True
o.item.set_is_selected (True)
else
o.item.set_is_selected (False)
end
end
if not l_found then
create opt.make (v, Void)
opt.set_is_selected (True)
add_option (opt)
end
else
across
options as o
loop
o.item.set_is_selected (False)
end
end
end
set_value (v: detachable WSF_VALUE)
do
if attached {WSF_STRING} v as s then
set_text_by_value (s.value)
else
set_text_by_value (Void)
end
end
add_option (opt: CMS_FORM_SELECT_OPTION)
do
options.force (opt)
end
feature -- Conversion
item_to_html (a_theme: CMS_THEME): STRING_8
local
l_is_already_selected: BOOLEAN
h: detachable STRING_8
do
Result := "<select name=%""+ name +"%" "
if css_id = Void then
set_css_id (name +"-select")
end
append_css_class_to (Result, Void)
append_css_id_to (Result)
append_css_style_to (Result)
if is_readonly then
Result.append (" readonly=%"readonly%" />")
else
Result.append ("/>")
end
across
options as o
loop
Result.append ("<option value=%"" + o.item.value + "%" ")
-- if not l_is_already_selected then
if
o.item.is_selected
then
l_is_already_selected := True
Result.append (" selected=%"selected%"")
end
-- end
Result.append (">" + o.item.text + "</option>%N")
if attached o.item.description as d then
if h = Void then
create h.make_empty
end
h.append ("<div id=%"" + name + "-" + o.item.value + "%" class=%"option%"><strong>"+ o.item.text +"</strong>:"+ d + "</div>")
end
end
Result.append ("</select>%N")
if h /= Void then
Result.append ("<div class=%"select help collapsible%" id=%"" + name + "-help%">" + h + "</div>%N")
end
end
end

View File

@@ -0,0 +1,58 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_FORM_SELECT_OPTION
inherit
CMS_FORM_SELECTABLE_ITEM
create
make
feature {NONE} -- Initialization
make (a_value: like value; a_text: detachable like text)
-- Initialize `Current'.
do
value := a_value
if a_text = Void then
text := a_value
else
text := a_text
end
end
feature -- Status
is_selected: BOOLEAN
is_same_value (v: READABLE_STRING_32): BOOLEAN
do
Result := value.same_string (v)
end
feature -- Access
value: READABLE_STRING_32
text: READABLE_STRING_8
description: detachable READABLE_STRING_8
feature -- Change
set_is_selected (b: like is_selected)
do
is_selected := b
end
set_description (d: like description)
do
description := d
end
end

View File

@@ -0,0 +1,25 @@
note
description: "Summary description for {CMS_FORM_SELECTABLE_ITEM}."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_FORM_SELECTABLE_ITEM
feature -- Status report
is_selected : BOOLEAN
deferred
end
is_same_value (v: READABLE_STRING_32): BOOLEAN
deferred
end
feature -- Change
set_is_selected (b: like is_selected)
deferred
end
end

View File

@@ -0,0 +1,21 @@
note
description: "Summary description for {CMS_FORM_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_SUBMIT_INPUT
inherit
CMS_FORM_INPUT
create
make,
make_with_text
feature -- Access
input_type: STRING = "submit"
end

View File

@@ -0,0 +1,21 @@
note
description: "Summary description for {CMS_FORM_TEXT_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_TEXT_INPUT
inherit
CMS_FORM_INPUT
create
make,
make_with_text
feature -- Access
input_type: STRING = "text"
end

View File

@@ -0,0 +1,90 @@
note
description: "Summary description for {CMS_FORM_INPUT}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_TEXTAREA
inherit
CMS_FORM_FIELD
create
make
feature {NONE} -- Initialization
make (a_name: like name)
do
name := a_name
end
feature -- Access
default_value: detachable READABLE_STRING_GENERAL
rows: INTEGER
cols: INTEGER
feature -- Element change
set_rows (i: like rows)
do
rows := i
end
set_cols (i: like cols)
do
cols := i
end
set_text_value (s: like default_value)
do
set_default_value (s)
end
set_value (v: detachable WSF_VALUE)
do
if attached {WSF_STRING} v as s then
set_text_value (s.value)
else
set_text_value (Void)
end
end
set_default_value (v: like default_value)
do
default_value := v
end
feature -- Conversion
item_to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<textarea name=%""+ name +"%""
if rows > 0 then
Result.append (" rows=%"" + rows.out + "%"")
end
if cols > 0 then
Result.append (" cols=%"" + cols.out + "%"")
end
append_css_class_to (Result, Void)
append_css_id_to (Result)
append_css_style_to (Result)
if is_readonly then
Result.append (" readonly=%"readonly%">")
else
Result.append (">")
end
if attached default_value as dft then
Result.append (a_theme.html_encoded (dft))
end
Result.append ("</textarea>")
end
end

View File

@@ -0,0 +1,22 @@
note
description: "Summary description for {CMS_FORM_UTILITY}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_FORM_UTILITY
feature -- Converter
html_encoded_string (s: READABLE_STRING_32): READABLE_STRING_8
do
Result := html_encoder.encoded_string (s)
end
html_encoder: HTML_ENCODER
once
create Result
end
end

View File

@@ -0,0 +1,83 @@
note
description: "Summary description for {WITH_CSS_CLASS}."
date: "$Date$"
revision: "$Revision$"
deferred class
WITH_CSS_CLASS
feature -- Status report
css_classes: detachable LIST [READABLE_STRING_8]
feature -- Change
reset_css_classes
do
css_classes := Void
end
add_css_class (a_class: READABLE_STRING_8)
require
is_valid_css_class: is_valid_css_class (a_class)
local
lst: like css_classes
do
lst := css_classes
if lst = Void then
create {ARRAYED_LIST [READABLE_STRING_8]} lst.make (1)
css_classes := lst
end
lst.force (a_class)
end
feature -- Query
is_valid_css_class (s: detachable READABLE_STRING_8): BOOLEAN
do
Result := s /= Void implies (not s.is_empty)
-- To complete
end
feature -- Conversion
append_css_class_to (a_target: STRING; a_additional_classes: detachable ITERABLE [READABLE_STRING_8])
local
f: BOOLEAN
cl: READABLE_STRING_8
do
if css_classes /= Void or a_additional_classes /= Void then
a_target.append (" class=%"")
f := True -- is first
if attached css_classes as l_classes then
across
l_classes as c
loop
cl := c.item
if not cl.is_empty then
if not f then
a_target.append_character (' ')
end
a_target.append (cl)
end
end
end
if attached a_additional_classes as l_classes then
across
l_classes as c
loop
cl := c.item
if not cl.is_empty then
if not f then
a_target.append_character (' ')
end
a_target.append (cl)
end
end
end
a_target.append_character ('%"')
end
end
end

View File

@@ -0,0 +1,41 @@
note
description: "Summary description for {WITH_CSS_ID}."
date: "$Date$"
revision: "$Revision$"
deferred class
WITH_CSS_ID
feature -- Status report
css_id: detachable READABLE_STRING_8
feature -- Change
set_css_id (a_id: like css_id)
require
is_valid_css_id: is_valid_css_id (a_id)
do
css_id := a_id
end
feature -- Query
is_valid_css_id (s: detachable READABLE_STRING_8): BOOLEAN
do
Result := s /= Void implies (not s.is_empty)
-- To complete
end
feature -- Conversion
append_css_id_to (a_target: STRING)
do
if attached css_id as l_id then
a_target.append (" id=%"")
a_target.append (l_id)
a_target.append_character ('%"')
end
end
end

View File

@@ -0,0 +1,31 @@
note
description: "Summary description for {WITH_CSS_STYLE}."
date: "$Date$"
revision: "$Revision$"
deferred class
WITH_CSS_STYLE
feature -- Status report
css_style: detachable CMS_CSS_STYLE
feature -- Change
set_css_style (a_style: like css_style)
do
css_style := a_style
end
feature -- Conversion
append_css_style_to (a_target: STRING)
do
if attached css_style as l_css_style then
a_target.append (" style=%"")
l_css_style.append_inline_to (a_target)
a_target.append_character ('%"')
end
end
end

View File

@@ -0,0 +1,36 @@
note
description: "Summary description for {CMS_EXTERNAL_MENU}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_EXTERNAL_LINK
inherit
CMS_LINK
create
make
feature {NONE} -- Initialization
make (a_title: like title; a_location: like location)
do
title := a_title
location := a_location
end
feature -- Status report
is_active: BOOLEAN = False
is_expanded: BOOLEAN = False
is_expandable: BOOLEAN = False
children: detachable LIST [CMS_LINK]
do
end
end

View File

@@ -0,0 +1,43 @@
note
description: "Summary description for {CMS_MENU}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_LINK
inherit
REFACTORING_HELPER
feature -- Access
title: READABLE_STRING_32
location: READABLE_STRING_8
options: detachable CMS_API_OPTIONS
feature -- status report
is_active: BOOLEAN
deferred
end
is_expanded: BOOLEAN
deferred
end
is_expandable: BOOLEAN
deferred
end
feature -- Query
parent: detachable CMS_LINK
children: detachable LIST [CMS_LINK]
deferred
end
end

View File

@@ -0,0 +1,72 @@
note
description: "Summary description for {CMS_LOCAL_MENU}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_LOCAL_LINK
inherit
CMS_LINK
create
make
feature {NONE} -- Initialization
make (a_title: detachable like title; a_location: like location)
do
if a_title /= Void then
title := a_title
else
title := a_location
end
location := a_location
end
feature -- Status report
is_active: BOOLEAN
is_expanded: BOOLEAN
is_expandable: BOOLEAN
permission_arguments: detachable ITERABLE [STRING]
children: detachable LIST [CMS_LINK]
feature -- Element change
set_children (lst: like children)
do
children := lst
end
set_expanded (b: like is_expanded)
do
is_expanded := b
end
set_expandable (b: like is_expandable)
do
is_expandable := b
end
get_is_active (req: WSF_REQUEST)
do
is_active := req.path_info.same_string (location)
end
set_permission_arguments (args: ITERABLE [STRING])
do
permission_arguments := args
end
set_options (opts: like options)
do
options := opts
end
end

View File

@@ -0,0 +1,73 @@
note
description: "Summary description for {CMS_MENU}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_MENU
inherit
ITERABLE [CMS_LINK]
create
make,
make_with_title
feature {NONE} -- Initialization
make (a_name: like name; n: INTEGER)
do
name := a_name
create items.make (n)
end
make_with_title (a_name: like name; a_title: READABLE_STRING_32; n: INTEGER)
do
make (a_name, n)
set_title (a_title)
end
feature -- Access
name: READABLE_STRING_8
title: detachable READABLE_STRING_32
items: ARRAYED_LIST [CMS_LINK]
extend (lnk: CMS_LINK)
do
items.extend (lnk)
end
remove (lnk: CMS_LINK)
do
items.prune_all (lnk)
end
feature -- status report
is_empty: BOOLEAN
do
Result := items.is_empty
end
feature -- Element change
set_title (t: like title)
do
title := t
end
feature -- Access
new_cursor: ITERATION_CURSOR [CMS_LINK]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
invariant
end

View File

@@ -0,0 +1,88 @@
note
description: "Summary description for {CMS_MENU_SYSTEM}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_MENU_SYSTEM
inherit
ITERABLE [CMS_MENU]
create
make
feature {NONE} -- Initialization
make
do
create items.make (5)
force (create {CMS_MENU}.make ("main-menu", 3))
force (create {CMS_MENU}.make_with_title ("management", "Management", 3))
force (create {CMS_MENU}.make_with_title ("navigation", "Navigation", 3))
force (create {CMS_MENU}.make_with_title ("user", "User", 3))
end
feature -- Access
item (n: like {CMS_MENU}.name): CMS_MENU
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
do
Result := item ("main-menu")
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)
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: HASH_TABLE [CMS_MENU, like {CMS_MENU}.name]
-- items: ARRAYED_LIST [CMS_MENU]
invariant
end

View File

@@ -0,0 +1,144 @@
note
description: "Summary description for {CMS_PAGER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_PAGER
create
make
feature {NONE} -- Initialization
make (tpl: READABLE_STRING_8; a_lower, a_upper: NATURAL_64; a_step: NATURAL_64)
do
create template.make (tpl)
lower := a_lower
upper := a_upper
step := a_step
end
feature -- Change
set_active_range (a_lower, a_upper: NATURAL_64)
do
if a_upper = 0 then
active_range := [{NATURAL_64} 1, {NATURAL_64} 0]
elseif a_lower > 0 and a_lower <= a_upper then
active_range := [a_lower, a_upper]
else
active_range := Void
end
ensure
valid_range: attached active_range as rg implies (rg.upper = 0 or else rg.lower <= rg.upper)
end
feature -- Access
template: URI_TEMPLATE
lower: NATURAL_64
upper: NATURAL_64
step: NATURAL_64
active_range: detachable TUPLE [lower_index, upper_index: NATURAL_64]
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
local
l_step: INTEGER
nb: INTEGER
curr: INTEGER
n, i: INTEGER
tb: HASH_TABLE [detachable ANY, STRING_8]
do
create Result.make (32)
Result.append ("<div")
Result.append_character ('>')
nb := ((upper - lower) // step).to_integer_32 + 1
if attached active_range as rg then
if rg.upper_index = 0 then
-- all
else
curr := ((rg.lower_index - lower) // step).to_integer_32
if step * curr.to_natural_64 < rg.lower_index then
curr := curr + 1
end
end
end
l_step := step.to_integer_32
create tb.make (2)
tb.force (1, "lower")
tb.force (step, "upper")
if curr > 1 then
if curr > 2 then
tb.force (1, "lower")
tb.force (l_step, "upper")
Result.append_character (' ')
Result.append (a_theme.link ("<<", template.expanded_string (tb), Void))
Result.append_character (' ')
end
tb.force ((curr - 1) * l_step + 1, "lower")
tb.force ((curr ) * l_step , "upper")
Result.append_character (' ')
Result.append (a_theme.link ("<", template.expanded_string (tb), Void))
Result.append_character (' ')
end
from
i := (curr - 1).max (1)
n := 5
until
n = 0 or i > nb
loop
Result.append_character (' ')
tb.force ((i - 1) * l_step + 1, "lower")
tb.force ((i ) * l_step , "upper")
if i = curr then
Result.append ("<strong>")
end
Result.append (a_theme.link (i.out, template.expanded_string (tb), Void))
if i = curr then
Result.append ("</strong>")
end
Result.append_character (' ')
i := i + 1
n := n - 1
end
if curr < nb then
Result.append_character (' ')
tb.force ((curr ) * l_step + 1, "lower")
tb.force ((curr + 1) * l_step , "upper")
Result.append (a_theme.link (">", template.expanded_string (tb), Void))
Result.append_character (' ')
if curr + 1 < nb then
tb.force ((nb - 1) * l_step + 1, "lower")
tb.force ( upper , "upper")
Result.append_character (' ')
Result.append (a_theme.link (">>", template.expanded_string (tb), Void))
Result.append_character (' ')
end
end
Result.append ("</div>")
Result.append ("curr=" + curr.out +" step=" + step.out + " nb=" + nb.out)
end
end

View File

@@ -0,0 +1,152 @@
note
description: "Summary description for {CMS_LOG}."
date: "$Date$"
revision: "$Revision$"
class
CMS_LOG
create
make
feature {NONE} -- Initialization
make (a_category: like category; a_message: like message; a_level: like level; a_date: detachable like date)
do
category := a_category
message := a_message
set_level (a_level)
if a_date = Void then
create date.make_now_utc
else
date := a_date
end
end
make_with_id (a_id: like id; a_category: like category; a_message: like message; a_level: like level; a_date: detachable like date)
do
id := a_id
make (a_category, a_message, a_level, a_date)
end
feature -- Access
id: INTEGER
-- Unique identifier of Current.
category: READABLE_STRING_8
-- Associated title (optional).
message: READABLE_STRING_8
-- Log message
level: INTEGER
-- Severity level
level_name: STRING
do
Result := level_to_string (level)
end
info: detachable READABLE_STRING_8
link: detachable CMS_LINK
date: DATE_TIME
feature -- status report
has_id: BOOLEAN
do
Result := id > 0
end
feature -- Change
set_id (a_id: like id)
require
not has_id
do
id := a_id
end
set_level (a_level: like level)
do
if a_level = 0 then
level := level_notice
else
level := a_level
end
end
set_link (lnk: like link)
do
link := lnk
end
set_info (inf: like info)
do
info := inf
end
feature -- Conversion
to_html (a_theme: CMS_THEME): STRING_8
do
Result := "<div class=%"log " + category + " " + level_name + "%" id=%"log-" + id.out + "%">"
Result.append ("<div class=%"inner%">")
Result.append (message)
if attached info as l_info then
Result.append ("<br/><strong>Information:</strong> ")
Result.append (l_info)
end
if attached link as lnk then
Result.append ("<br/><strong>Associated link:</strong> ")
Result.append (a_theme.link (lnk.title, lnk.location, lnk.options))
end
Result.append ("</div>")
Result.append ("<div class=%"description%">")
Result.append ("(date: " + date.year.out + "/" + date.month.out + "/" + date.day.out + ")")
Result.append ("</div>")
Result.append ("</div>")
end
feature -- Constants
level_to_string (a_level: INTEGER): STRING
do
inspect a_level
when level_emergency then
Result := "emergency"
when level_alert then
Result := "alert"
when level_critical then
Result := "critical"
when level_error then
Result := "error"
when level_warning then
Result := "warning"
when level_notice then
Result := "notice"
when level_info then
Result := "info"
when level_debug then
Result := "debug"
else
Result := "level-" + a_level.out
end
end
level_emergency: INTEGER = 1
level_alert: INTEGER = 2
level_critical: INTEGER = 3
level_error: INTEGER = 4
level_warning: INTEGER = 5
level_notice: INTEGER = 6
level_info: INTEGER = 7
level_debug: INTEGER = 8
end