note
description: "Collection of helper routines to manipulate URL for CMS."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_URL_UTILITIES
inherit
CMS_ENCODERS
feature -- Core
site_url: READABLE_STRING_8
-- Absolute site URL of Current CMS site.
deferred
end
base_url: detachable READABLE_STRING_8
-- Base url if any.
deferred
end
based_path (p: READABLE_STRING_8): STRING_8
-- Path `p' in the context of the `base_url'
do
if attached base_url as l_base_url and then not l_base_url.is_empty then
if p.starts_with (l_base_url) then
-- In case `p` is already based on base_url.
check starts_with_slash: p.starts_with ("/") end
Result := p.to_string_8
else
create Result.make_from_string (l_base_url)
if p.is_empty then
else
if p[1] /= '/' then
Result.extend ('/')
end
Result.append (p)
end
end
else
if p.is_empty then
Result := "/"
elseif p[1] /= '/' then
create Result.make_from_string (p)
Result.precede ('/')
else
Result := p.to_string_8
end
end
end
feature -- Link
link (a_text: detachable READABLE_STRING_GENERAL; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
-- HTML link with title `a_text' and href `a_path'.
-- `opts' is used for additional settings.
do
create Result.make (32)
append_link_to_html (a_text, a_path, opts, Result)
end
absolute_link (a_text: detachable READABLE_STRING_GENERAL; a_path: READABLE_STRING_8; a_opts: detachable CMS_API_OPTIONS): STRING
-- HTML link with title `a_text' and href `a_path'.
-- `opts' is used for additional settings.
local
opts: CMS_API_OPTIONS
do
create opts.make (1)
if a_opts /= Void then
opts.import (a_opts)
end
opts.force (True, "absolute")
create Result.make (32)
append_link_to_html (a_text, a_path, opts, Result)
end
link_with_raw_text (a_raw_text: detachable READABLE_STRING_8; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING
-- HTML link with title the html code `a_raw_text' and href `a_path'.
-- `opts' is used for additional settings.
do
create Result.make (32)
append_link_with_raw_text_to_html (a_raw_text, a_path, opts, Result)
end
append_cms_link_to_html (lnk: CMS_LINK; opts: detachable CMS_API_OPTIONS; a_html: STRING_8)
do
append_link_to_html (lnk.title, lnk.location, opts, a_html)
end
append_link_to_html (a_text: detachable READABLE_STRING_GENERAL; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS; a_html: STRING_8)
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
a_html.append ("")
if a_text = Void then
t := a_path
else
t := a_text
end
if l_html then
a_html.append (html_encoded (t))
else
a_html.append (checked_plain (t))
end
a_html.append ("")
end
append_link_with_raw_text_to_html (a_raw_text: detachable READABLE_STRING_8; a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS; a_html: STRING_8)
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
a_html.append ("")
if a_raw_text = Void then
t := a_path
else
t := a_raw_text
end
a_html.append (t)
a_html.append ("")
end
feature -- Url
absolute_url (a_path: READABLE_STRING_8; opts: detachable CMS_API_OPTIONS): STRING_8
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_8
-- URL for path `a_path' and optional parameters from `opts'.
-- Caller can also use specific CMS_API_URL_OPTIONS (descendant of CMS_API_OPTIONS)
--| Options `opts' could be
--| - absolute: True|False => return absolute url
--| - query: string => append "?query"
--| - fragment: string => append "#fragment"
local
q: detachable STRING_8
f: detachable READABLE_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.to_string_8
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.to_string_8
end
else
Result := based_path (a_path)
end
if q /= Void then
Result.append_character ('?')
Result.append (q)
end
if f /= Void then
Result.append_character ('#')
Result.append (f)
end
end
checked_url (a_url: READABLE_STRING_8): READABLE_STRING_8
do
-- FIXME: implement a way to check if `a_url' is safe, and does not reveal security issue.
Result := a_url
end
checked_plain (a_text: READABLE_STRING_GENERAL): STRING_8
do
Result := html_encoded (a_text)
end
note
copyright: "2011-2022, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end