Menu

[r1673]: / framework / trunk / cppcms / url_mapper.h  Maximize  Restore  History

Download this file

280 lines (261 with data), 9.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef CPPCMS_URL_MAPPER_H
#define CPPCMS_URL_MAPPER_H
#include <cppcms/defs.h>
#include <booster/noncopyable.h>
#include <booster/hold_ptr.h>
#include <cppcms/filters.h>
#include <string>
#include <vector>
namespace cppcms {
class application;
///
/// \brief class for mapping URLs - the opposite of dispatch
///
/// This class is useful for mapping between different page identifications
/// that represent different classes/view and the URL.
///
///
/// The URL mapping is done in hierarchy of applications where each application
/// has its own name and they bundler into single hierarchy. Each application in hierarchy
/// can be referred by its key and location. It may have different "urls" for mapping
/// different values.
///
/// For example, we develop a content management system with following tools:
///
/// - site
/// - news
/// - article
/// - category
/// - forums
/// - topics
/// - threads
/// - users
/// - management
/// - registration
/// - profile
///
/// Each node above is represented my cppcms::application and its children mounted
/// to it. In order to access each URL we use "file system" like convention:
///
/// - "/" - the default site page
/// - "/news" - the default news page
/// - "/news/article" - the default article page
/// - "/news/category/by_date" - the categories pages sorted by data
/// - "/news/category/by_interest" - the categories pages sorted by interest
/// - "/news/category" - the default category pages
///
/// And so on.
///
/// Each application can be referred by its full path from root or by its relative path,
/// so if we for example in article sub-application and we want to refer to "category"
/// URL we would use something like map(out(),"../category/by_interest",category_id);
///
/// In order to all this process work, each application should mount its children by some name,
/// like:
///
/// \code
/// site::site(cppcms::service &s) :
/// cppcms::application(s),
/// news_(s),
/// forums_(s),
/// users_(s)
/// {
/// add(news_);
/// mapper().mount("news","/news{1}",news_);
/// add(forums_);
/// mapper().mount("forums","/forums{1}",forums_);
/// ...
/// \endcode
///
/// You can also use cppcms::application::add and cppcms::application::attach that allows
/// to provide mapping for url_dispatcher and url_mapper in a single command like:
///
/// \code
/// add(news_,
/// "news","/news{1}",
/// "/news((/.*)?)",1);
/// \endcode
///
/// Which effectively the same as:
///
/// \code
/// add(news_);
/// mapper().mount("news","/news{1}",news_);
/// dispatcher().mount("/news((/.*)?)",news_,1);
/// \endcode
///
/// Such system allows using "url" tag in templates system easily as"
///
/// \code
/// <a href="/?originalUrl=https%3A%2F%2Fsourceforge.net%2F%26quot%3B%26lt%3B%25%2520url%2520%26quot%3B%2Fnews%2Farticle%26quot%3B%2520using%2520article%2520id%2520%25%26gt%3B%26quot%3B%2520%26gt%3B...%26lt%3B%2Fa%26gt%3B%253C%2Fspan">
/// \endcode
///
/// Each mounted application may a default URL (something like index.html)
/// which is mapped when mounted application is referred. So for example there
/// are may be following URLs:
///
/// - "/news/article" or "/news/article/" - the default URL
/// - "/news/article/preview" - preview unpublished article URL.
///
/// They can be defined in article class as following:
///
/// \code
/// article::article(cppcms::service &s) : cppcms::application(s)
/// {
/// mapper().assign("/{1}"); // the default URL
/// dispatcher().assign("/(\\d+)",&article::display,this,1);
/// mapper().assign("preview","/{1}/preview"); // the preview URL
/// dispatcher().assign("/(\\d+)/preview",&article::preview,this,1);
/// }
/// \endcode
///
///
class CPPCMS_API url_mapper : public booster::noncopyable {
public:
/// \cond INTERNAL
url_mapper(application *app);
~url_mapper();
/// \endcond
///
/// Get the root of the application - the string that
/// is added to the any URL patter like "/forum" or
/// "http://my.site.com"
///
std::string root();
///
/// Set the root of the application - the string that
/// is added to the any URL patter like "/forum" or
/// "http://my.site.com"
///
void root(std::string const &r);
///
/// Provide a mapping between special \a key and a \a url pattern.
///
/// URL patter is a string that includes mapped patters between "{" and "}"
/// brackets. For example "/page/{1}" where "{1}" is being substituted
/// by the first parameter in map functions.
///
/// The ids can be numbers - 1 to 4 and special keys that can be changed
/// in the run time using set_value functions. For example:
///
/// "/wiki/{lang}/page/{1}"
///
/// Where "lang" can be defined by "set_value". For example.
///
/// For the url above with "lang" set to "en" and first parameter "cppcms"
/// the string would be "/wiki/en/page/cppcms"
///
/// Note the keys may be overloaded by number of parameters as for example:
///
/// - <tt>assign("page","/wiki/{1}/page/{2}");</tt>
/// - <tt>assign("page","/wiki/{lang}/page/{1}");</tt>
/// - <tt>assign("page","/wiki/{lang}/page/main");</tt>
///
/// Then map(output,"page") - would create "/wiki/en/page/main",
/// map(output,"page",134) would create "/wiki/en/page/132" and
/// map(output,"page","ru","cppcms") would create "/wiki/ru/page/cppcms"
///
/// Note: They keys containing "/" or keys with values "..", ".", "" are prohibited
/// as they have special meanings
///
void assign(std::string const &key,std::string const &url);
///
/// Map the default key for the application, \a url has same rules as for assign(key,url) but
/// they rather refer to default application's URL when it is used in hierarchy.
///
void assign(std::string const &url);
///
/// Set special value for a key that would be used
/// in URL mapping, for example set_value("lang","en")
///
void set_value(std::string const &key,std::string const &value);
///
/// Clear the special value - reset to empty
///
void clear_value(std::string const &key);
///
/// Write the URL to output stream \a out for the URL \a path with 0 parameters
///
void map( std::ostream &out,
std::string const &path);
///
/// Write the URL to output stream \a out for the URL \a path with 1 parameters
///
void map( std::ostream &out,
std::string const &path,
filters::streamable const &p1);
///
/// Write the URL to output stream \a out for the URL \a path with 2 parameters
///
void map( std::ostream &out,
std::string const &path,
filters::streamable const &p1,
filters::streamable const &p2);
///
/// Write the URL to output stream \a out for the URL \a path with 3 parameters
///
void map( std::ostream &out,
std::string const &path,
filters::streamable const &p1,
filters::streamable const &p2,
filters::streamable const &p3);
///
/// Write the URL to output stream \a out for the URL \a path with 4 parameters
///
void map( std::ostream &out,
std::string const &path,
filters::streamable const &p1,
filters::streamable const &p2,
filters::streamable const &p3,
filters::streamable const &p4);
///
/// Mount sub application \a app using name \a name to a \url.
///
/// The URL format as in assign but it requires a single parameter {1}
/// which would be substituted with the mapping of the URL of sub-application
/// instead of using "root" patch
///
void mount(std::string const &name,std::string const &url,application &app);
///
/// Get a mapper of mounted application by its name
///
url_mapper &child(std::string const &name);
///
/// Get a parent mapper, if not exists throws cppcms_error
///
url_mapper &parent();
///
/// Get a topmost mapper, if have no parents returns reference to \c this.
///
url_mapper &topmost();
private:
void real_assign(std::string const &key,std::string const &url,application *child = 0);
url_mapper &get_mapper_for_key(std::string const &key,std::string &real_key);
url_mapper *root_mapper();
void real_map( std::string const key,
filters::streamable const *const *params,
size_t params_no,
std::ostream &output);
struct data;
booster::hold_ptr<data> d;
};
};
#endif
MongoDB Logo MongoDB