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.
|