webmcp
view framework/env/encode/url.lua @ 455:e2389cc82214
Improved include_tempstore argument to request.redirect{...}
| author | jbe | 
|---|---|
| date | Thu Jul 21 19:23:23 2016 +0200 (2016-07-21) | 
| parents | 1b380a0ab940 | 
| children | 
 line source
     1 --[[--
     2 url_string =             -- a string containing an URL
     3 encode.url{
     4   external = external,   -- external URL (instead of specifying base, module, etc. below)
     5   base     = base,       -- optional string containing a base URL of a WebMCP application
     6   static   = static,     -- an URL relative to the static file directory
     7   module   = module,     -- a module name of the WebMCP application
     8   view     = view,       -- a view name of the WebMCP application
     9   action   = action,     -- an action name of the WebMCP application
    10   id       = id,         -- optional id to be passed to the view or action to select a particular data record
    11   params   = params,     -- optional parameters to be passed to the view or action
    12   anchor   = anchor      -- anchor in URL
    13 }
    15 This function creates URLs to external locations, to static files within the WebMCP application or to a certain view or action inside a module.
    17 --]]--
    19 function encode.url(args)
    20   local external  = args.external
    21   local base      = args.base or request.get_relative_baseurl()
    22   local static    = args.static
    23   local module    = args.module
    24   local view      = args.view
    25   local action    = args.action
    26   local id        = args.id
    27   local params    = args.params or {}
    28   local anchor    = args.anchor
    29   local result    = {}
    30   local id_as_param = false
    31   local function add(...)
    32     for i = 1, math.huge do
    33       local v = select(i, ...)
    34       if v == nil then break end
    35       result[#result+1] = v
    36     end
    37   end
    38   if external then
    39     add(external)
    40   else
    41     add(base)
    42     if not string.find(base, "/$") then
    43       add("/")
    44     end
    45     if static then
    46       add("static/")
    47       add(static)
    48     elseif module or view or action or id then
    49       assert(module, "Module not specified.")
    50       add(encode.url_part(module), "/")
    51       if view and not action then
    52         local view_base, view_suffix = string.match(
    53           view,
    54           "^([^.]*)(.*)$"
    55         )
    56         add(encode.url_part(view_base))
    57         if args.id then
    58           add("/", encode.url_part(id))
    59         end
    60         if view_suffix == "" then
    61           add(".html")
    62         else
    63           add(view_suffix)  -- view_suffix includes dot as first character
    64         end
    65       elseif action and not view then
    66         add(encode.url_part(action))
    67         id_as_param = true
    68       elseif view and action then
    69         error("Both a view and an action was specified.")
    70       end
    71     end
    72     do
    73       local new_params = request.get_perm_params()
    74       for key, value in pairs(params) do
    75         new_params[key] = value
    76       end
    77       params = new_params
    78     end
    79   end
    80   if next(params) ~= nil or (id and id_as_param) then
    81     if not (external and string.find(external, "%?")) then
    82       add("?")
    83     elseif external and not string.find(external, "&$") then
    84       add("&")
    85     end
    86     if id and id_as_param then
    87       add("_webmcp_id=", encode.url_part(id), "&")
    88     end
    89     for key, value in pairs(params) do
    90       -- TODO: better way to detect arrays?
    91       if string.match(key, "%[%]$") then
    92         for idx, entry in ipairs(value) do
    93           add(encode.url_part(key), "=", encode.url_part(entry), "&")
    94         end
    95       else
    96         add(encode.url_part(key), "=", encode.url_part(value), "&")
    97       end
    98     end
    99     result[#result] = nil  -- remove last '&' or '?'
   100   end
   101   local string_result = table.concat(result)
   102   if anchor ~= nil then
   103     string_result = string.match(string_result, "^[^#]*")
   104     if anchor then
   105       string_result = string_result .. "#" .. encode.url_part(anchor)
   106     end
   107   end
   108   return string_result
   109 end
