When inserting a widget in the widget hierarchy, ownership is transferred to its parent in the tree. Thus, when deleting a widget, all of its children are deleted as well, significantly reducing the burden of memory management related to widgets. When the WApplication object is deleted, the root of the tree is deleted, and in this way all resources associated with any widget are free'd.
Any descendent class of WWidget is a self-contained (reusable) class that encapsulates both the look and behaviour, enabling the design of the user interface in am orthogonal way.
CSS layout considers two important categories of layout. Text-like layout (inline) flow with sibling inline widgets in lines, wrapping at the right edge of the parent container. In contrast, widgets displayed as a block stack vertically with respect to sibling widgets.
Layout managers are implemented in WLayout and descendant classes. They can be used in conjunction with WContainerWidget or Ext::Container container classes. Note that some layout managers are applicable only to a WContainerWidget and some only to an Ext::Container. Due to limitations in CSS (and pedantic browser implementations), vertical layout is not possible without JavaScript.
CSS Style selectors may be used in conjunction with widget style classes that may be set for any widget using WWidget::setStyleClass(). The recommended way for visual response to events is by changing the style class for the widget.
In addition to configuration using style sheets, Wt also supports the direct manipulation of a widget's style, using WWidget::decorationStyle().
Widgets may also be added to an Ext::Container, through a choice of layout manager, (see Ext::Container::setLayout()).
To effectively change the internal path and obtain consistent behaviour with or without JavaScript, you should use a WAnchor to let the user switch to a new internal path. The easiest way to do this is by using the WAnchor::setRefInternalPath(). This refers the WAnchor to a URL generated by WApplication::bookmarkUrl() for the new internal path (handling the plain HTML case), and binds a JavaScrit slot to its WAnchor::clicked() signal, which changes the internal path (handling the AJAX case).
Finally, you can listen for path changes using the WApplication::internalPathChanged() event to react to the user navigating through his history or opening a bookmarked internal page.
To avoid reloading the application (and spawning a new session) each time the internal path is changed, when AJAX is available, the internal path is indicated using a name anchor (#) after the deployment URL. For a plain HTML session, the session ID is appended to the URL to avoid the session from reloading when the user navigates using a WAnchor to a new internal URLs.
When your applications uses internal URLs, this has consequences for relative URLs to external resources (style sheets, images, JavaScript files, etc...), since these are resolved taking into account the current relative URL. All relative URLs that are known to the application (e.g. those set in WAnchor::setRef(), WImage::setImageRef(), WApplication::useStyleSheet(), etc...) are automatically replace by Wt with an absolute URL that resolves these directly within the deployment location. You should use absolute URLs in CSS or XHTML for them to work within each internal path, since these cannot be fixed by Wt.
For every new session (which corresponds to a new user surfing to your web application), the library calls your createApplication callback function to create a new WApplication object for that session. The request arguments (as part of the WEnvironment object) are passed to this createApplication function, and may be used to customize the application or authenticate the user. See also 6. Application bootstrap for details on the application bootstrap method.
At all times, the WApplication instance is accessible using the static method WApplication::instance(), and is useful to inspect startup arguments and settings (using WApplication::environment()), to set or change the application title (WApplication::setTitle()), to specify a locale (WApplication::setLocale()) for rendering, and many other application-wide settings.
A session exits when the user browses away from the application, when WApplication::quit() is called, or when the application server is shut down. In any case, the application object together with the entire widget tree for that session is first properly deleted. Therefore, you should release resources held by your widgets or application in the destructors of these objects.
The library offers two different mechanisms to map sessions onto processes: dedicated processes (only with FastCGI deployment) and shared processes. The first mechanisms forks a dedicated process for every distinct session. This provides the kernel-level isolation of different sessions, which may be useful for highly security sensitive applications. The second mechanism spawns a number of processes and allocates new sessions randomly to one of these processes (when using the built-in httpd, only one process is used in total). This reduces the danger for DoS attacks, but requires more careful programming as memory corruption affects all sessions in a single process, and sessions are not isolated by any other mechanism but correct programming.
A slot is any method of any descendant of WObject. To connect a signal with a slot, the only requirement is that the method signature of the slot must be compatible with the signal definition. In this way every method may be used as a slot, and it is not necessary to explicitly indicate a particular method to be a slot (as is needed in Qt), by putting them in a special section. Nevertheless, you may still do that if you wish to emphasize that these functions can be used as slots, or, if you have done extra work to optimize the implementation of these methods as client-side JavaScript code (see below).
A signal may be created by adding a Signal<X, ...> object. You may specify up to 6 arguments which may be of arbitrary types that are Copyable, that may be passed through the signal to connected slots.
The library defines several user-event signals on various widgets, and it is easy and convenient to add signals and slots to widget classes to communicate events and trigger callbacks.
Event signals (EventSignal<E>) are signals that may be triggered internally by the library to respond to user interactivity events. The abstract base classes WInteractWidget and WFormWidget define most of these event signals. To react to one of these events, the programmer connects a self-defined or already existing slot to such a signal.
However, Wt offers several options for incorporating client-side event handling. This may in general increase responsiveness of the application since the user gets an instant feed-back, avoiding the typical communication delay is avoided.
The least flexible but most convenient option for client-side event handling is letting Wt learn the visual effect of a slot and cache it in JavaScript code in the browser. In this way, the functionality is still specified in C++, and therefore the application still works equally when JavaScript is not available. The only restriction is that this is only possible for stateless call-back code -- i.e. when the visual update does not depend on state that may change in the course of the application, or event details. See the documentation of WObject::implementStateless for details, or the Treelist example for the use of stateless implementations to create a treelist widget that does all node expansion / collapsing client-side, at least if JavaScript is available.
The stateless slot learning allows applications to be developed entirely in C++, with only one specification of the desired behaviour, and decide at run-time to optimize certain event handling in client-side JavaScript if possible, and fall-back to server-side event handling otherwise.
When the requirements for stateless slot learning cannot be met you will have to resort to writing JavaScript manually. Wt provides a number of mechanisms to integrate JavaScript code with C++:
Wt.emit()
. In this mode, the application is not started until the library has determined AJAX support, which is made available in WEnvironment::ajax() which is passed to the application constructor.
In some special cases, this bootstrap is skipped and a plain HTML version is served. This is for user agents that are identified as spider bots, or user agents which are configured to not support AJAX (well), see the user-agents configuration setting.
There are some draw-backs to this bootstrap method:
This bootstrap method may be enabled with the progressive-bootstrap configuration setting.
This bootstrap method will initially assume that the user agent is a plain HTML user-agent and immediately create the application (with WEnvironment::ajax() always returning false
). The initial response will contain the initial page suitable for a plain HTML user-agent.
JavaScript embedded in this page will sense for AJAX support and trigger a second request which progresses the application to an AJAX application (without repainting the user interface). To that extent, it will change WEnvironment::ajax() to return true
, and invoke WApplication::enableAjax() which in turn propagates WWidget::enableAjax() through the widget hierarchy. This upgrade happens in the back-ground, unnoticed to the user.
This mitigates disadvantages associated with the default bootstrap, but has the draw-backs of being new, and it requires more server-side processing.
resources/
folder. In addition, any auxiliary files you use, such as message resource files, graphics, static pages, or anything else, will also need to be deployed./etc/wt/wt_config.xml
, and can be overridden with the WT_CONFIG_XML environment variable or the --config
startup parameter for wthttpd).The configuration file may specify several <application-settings>. The settings that apply are determined by the location attribute. Application settings for the '*' location are general settings, which may be overridden on a per-application level by settings with a location attribute that matches the location of the application (on the file system).
X-Forwarded-For
header, if present.
By default, Wt does a browser detection to distinguish between the first two: if a browser supports JavaScript (and has it enabled), and has an AJAX DOM API, then AJAX sessions are chosen, otherwise plain HTML sessions.
Here, you may indicate which user agents should or should not receive an AJAX session regardless of what they report as capabilities, and which user agents should be treated as search bots.
<properties> <property name="extBaseURL">/ext/</property> </properties>
debug
is passed to the application as last request parameter.
General options: -h [ --help ] produce help message -t [ --threads ] arg (=10) number of threads --servername arg (=localhost) servername (IP address or DNS name) --docroot arg document root for static files --errroot arg root for error pages --accesslog arg access log file (defaults to stdout) --no-compression do not compress dynamic text/html and text/plain responses --deploy-path arg (=/) location for deployment --session-id-prefix arg prefix for session-id's (overrides wt_config.xml setting) -p [ --pid-file ] arg path to pid file (optional) -c [ --config ] arg location of wt_config.xml. If unspecified, WT_CONFIG_XML is searched in the environment, if it does not exist then the compiled-in default (/etc/wt/wt_config.xml) is tried. If the default does not exist, we revert to default values for all parameters. HTTP server options: --http-address arg IPv4 (e.g. 0.0.0.0) or IPv6 Address (e.g. 0::0) --http-port arg (=80) HTTP port (e.g. 80) HTTPS server options: --https-address arg IPv4 (e.g. 0.0.0.0) or IPv6 Address (e.g. 0::0) --https-port arg (=443) HTTPS port (e.g. 443) --ssl-certificate arg SSL server certificate chain file e.g. "/etc/ssl/certs/vsign1.pem" --ssl-private-key arg SSL server private key file e.g. "/etc/ssl/private/company.pem" --ssl-tmp-dh arg File for temporary Diffie-Hellman parameters e.g. "/etc/ssl/dh512.pem"
Generated using WApplication::log(), e.g.:
wApp->log("notice") << "Message";
Generated using WApplication::log(), e.g.:
wApp->log("warn") << "Message";
Generated using WApplication::log(), e.g.:
wApp->log("error") << "Message";
Generated by throwing a std::exception.
You can now proceed to the Treelist example