Re: [Cppcms-users] url mapper
Brought to you by:
artyom-beilis
From: Markus R. <us...@ma...> - 2012-03-07 14:45:35
|
Hi! Thanks for your detailled answer! The problems with the plugin and localization are now resolved, too. Artyom Beilis wrote: >>> my_stream.imbue(context().locale()); >> >>That is working. >> >>I was asking myself how the booster::locale::translate is working within >>plugins. In the main program translate() is working, but not in the >>plugins. I did not called std::locale::global(gen("")); >> > > See: > > stream << booster::locale::translate("foo") > > Works because actual translation is postponed to the > stage were the data is written to the stream and rendered withing it. > > booster::locale::translate-> booster::locale::message + std::ostream's > locale gives translation. > > So if you want to use locale for your plugin you need to have some locale > context. It can be done by > > std::string translated = app.translate("foo"); > > or use locale explicitly as: > > std::locale loc = app.context().locale(); > std::string translated = booster::locale::translate("foo").str(loc); > > > or > > std::locale loc = app.context().locale(); > std::string translated = booster::locale::gettext("foo",loc); > > > Of course if your application uses only one language globally > you can just set std::locale::global. Thanks, I think we now have every option available. I found a method for every problem! >>But if it does not work well - see problem below - I may change to use >>render() template. I do not understand the "With the command render" >>example: In std::string main_html(cppcms::applicatin *app) the plugin >>still renders to a buffer and returs the string, so what is the >>difference? >> > > It was just an example > > However, if you call <% render ... %> from the view it renders to the > output stream without intermediate buffers. My plugin has a print(ostream& ) function and the print() is wrapped in a cppcms::filters::streamable main which is printed by <%= main | raw %>. There should also be no intermediate buffer, or? >>E.g. I have the following code: > >> >>17 void My_plugin::do(std::ostream & buf, cppcms::application & app) >>18 { >>19 if(app.request().request_method()=="POST") >>20 { >>21 m_main.m_form.load(app.context()); >>22 m_main.m_form.validate(); >>23 ::std::cout << "x is: " << m_main.m_form.x.value() << >>std::endl; >>24 m_main.m_form.clear(); >>25 } >>26 >>27 app.render("plugin_skin","main_html",buf,m_main); >>28 } >> >>Then I get following exception: >>2012-03-06 09:52:08; cppcms, error: Caught exception [Value was not >>loaded] 0x40566414: booster::stack_trace::trace(void**, int) + 0x24 in >>/usr/lib/libbooster.so.0 >>0x4015fe9b: cppcms::widgets::base_text::value() + 0xcb in >>/usr/lib/libcppcms.so.1 >>0x43132180: My_plugin::do(std::ostream&, cppcms::application&) in line 23 >> > > I think you had not added m_form.x to m_form (using m_form.add(x)); > so when you access x.value() it appears not to be loaded when you > call load(app.context()); You are completely right! Thanks a lot! I suggest to change the text "Value was not loaded" to something like "The value or the parent was not loaded. Check the hierarchy." ;) >> Is there some explanation how this works if multiple applications are >> mounted at the same root? > > The behavior is undefined for `cppcms::application_pool` Mmmh, but exactly this happens when you use the file server? It is also mounted at "". > Generally the first one will be selected, but non necessary, it > may be changed in future. So you should provide mutually > exclusive mount points. I do not have that situation within my own framework. > The dispatching and matching withing application (url_dispatched) is done > according to the order of adding them to url_dispatcher. Ok, good to know. >>> Because when you map sub-application and refer to it >>> you automatically referred to the default URL >>> of the sub-application - empty one "empty key" >> >>Sorry, I do not understand this statement. >> > > First of all take a look on this tutorial carefully. > > http://cppcms.com/wikipp/en/page/cppcms_1x_tut_hierarchy > > > >>There are some examples for mapper and dispatcher, but I can't find >>anything related to how the url() call works. >>Doxygen just says: "Map url-key key to actual URL, without parameters" > >>What does url("gui") does? >> > > application::url() and <% url ... %> is a family of functions with > variable number of parameters. How does the <% url ... %> using syntax work? Why does <% url "/blog/post" using slug %> resolves to "/myblog/Hi%20%3cyou%3e/" (see http://cppcms.com/wikipp/en/page/cppcms_1x_templates_comm#URL.Mapping) I would rather expect /blog/post/Hi%20%3cyou%3e/? Both <% url "/gui/system" %> <% url "system" %> work without problem, but I could not figure out how to resolve a variable containing "system"? E.g. <% url "/gui/" using menu_element.m_href %> does not work? > when you call url("foo") it looks for the object named "foo" > > If it is actual function (not sub application) it provides a url > > if it is subapplication it tries to dispatch the "" key. Ok, I think I understand the approach now much better. I still can't figure out the details between: url("") url(".") url("/") while the first two seem to be equivalent, url("/") seems to link to the same url where the request() came from? e.g. when I request http://localhost:10000/gui/wrong_url url("/") resolves to http://localhost:10000/gui/wrong_url but url("") and url(".") resolves to ttp://localhost:10000/gui When I use dispatcher().assign("", &GUI::show_error_page, this); mapper().assign("/"); // changed here instead of "" the urls resolve to: url("/") -> http://localhost:10000/gui/wrong_url url(".") -> http://localhost:10000/gui/ url("") -> http://localhost:10000/gui/ So url(".") with assign("/") seems to be what I want ;) > See, applications are generated in the hierary, so > > For given application: foo, sub application bar and bar's method baz > > url("/foo/bar/baz") would map to the "baz"'s url. > > url("/foo/bar") would map to default (empty) url of baz application. > > You can have parameters as well for example > > // withing bar > > mapper().assign("baz","/baz"); > mapper().assign("baz","/baz/{1}"); > mapper().assign("baz","/baz/{1}/{2}"); > > Then you can call: > > url("/foo/bar/baz") -> something/baz > url("/foo/bar/baz",20) -> something/baz/20 > url("/foo/bar/baz","x","y") -> something/baz/x/y Thanks, I think I do not need parameters, because I prefer to have user/browser specific language and not by url. >>Can I use mapper().set_value? >> >> > > set_value should be used for some horizontal parameters > like for example language when you want to change the URL > independently from, the hierary. > > mapper().set_value("lang","en") > url("/foo/bar") -> en.wiki.org/foo/bar > url("/baz") -> en.wiki.org/baz > > mapper().set_value("lang","he") > url("/foo/bar") -> he.wiki.org/foo/bar > url("/baz") -> he.wiki.org/baz Ok, thank you! >>I think copy&paste of how wikipp does + explanation would help, because >>the > >>redirecting + url resolving there is what most users want anyway. >> > > Actually, wikipp was written before URL-mapper existed and I had > no time to update it. Take a look rather on the cppcms's blog > it uses url mapper fully. Ok, so I think the examples you gave in this mail are perfect! > P.S.: URL Mapper/Dispatcher is actually not-so simple and powerful part > I need to write a better tutorial. Yeah, they are powerful, I like them :-) best regards Markus |