Re: [Cppcms-users] Plugins, Localization, url mapper
Brought to you by:
artyom-beilis
From: Artyom B. <art...@ya...> - 2012-03-06 21:06:06
|
>> >> 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. > >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. >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()); > > Is there some explanation how this works if multiple applications are > mounted at the same root? The behavior is undefined for `cppcms::application_pool` Generally the first one will be selected, but non necessary, it may be changed in future. So you should provide mutually exclusive mount points. The dispatching and matching withing application (url_dispatched) is done according to the order of adding them to url_dispatcher. >> >> 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. 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. 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 >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 >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. Regards, Artyom Beilis, P.S.: URL Mapper/Dispatcher is actually not-so simple and powerful part I need to write a better tutorial. |