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
|