+
+
+```
+
+In the login action, you can write the authentication process that is executed when a user name and a password are posted. Once the authentication was successful, call the userLogin() method and then let the user login to the system.
+
+```c++
+void AccountController::login()
+{
+ QString username = httpRequest().formItemValue("username");
+ QString password = httpRequest().formItemValue("password");
+
+ User user = User::authenticate(username, password);
+ if (!user.isNull()) {
+ userLogin(&user);
+ redirect(QUrl(...));
+ } else {
+ QString message = "Login failed";
+ texport(message);
+ render("form");
+ }
+}
+```
+
+- If you do not include the *user.h* file it would cause a compile-time error.
+
+That completes the login process.
+Although not included in the code above, it is recommended to call the userLogin() method once the user is logged in order to check for any duplicate login(s). Checking the return value (bool) is therefore advised.
+
+After calling the userLogin() method, the return value of identityKey() method of user model is stored into the session. By default, a user name is stored.
+
+```c++
+ QString identityKey() const { return username(); }
+```
+
+You can modify the return value, which should be unique in your system. For example, you can let return a primary key or ID and then can get the value by calling the identityKeyOfLoginUser() method.
+
+## Logout
+
+To log out, all you need to do is simply to call the userLogout() method in the action.
+
+```c++
+void AccountController::logout()
+{
+ userLogout();
+ redirect(url("Account", "form")); // redirect to a login form
+}
+```
+
+## Checking Logging In
+
+If you want to prevent access from users who are not logged, you can override the preFilter() of controller. Write that process there.
+
+```c++
+bool HogeController::preFilter()
+{
+ if (!isUserLoggedIn()) {
+ redirect( ... );
+ return false;
+ }
+ return true;
+}
+```
+
+When the preFilter() method returns *false*, the action will not be processed after this.
+If you would like to restrict access in many controllers, you can set it to preFilter() of the ApplicationController class.
+
+## Getting the Logged-in User
+
+First of all, we need to get an instance of the logged-in user. You can get the identity information of the logged-in user by the identityKeyOfLoginUser() method. If the return value is empty, it indicates that nobody is logging in the session; otherwise the value is a user name from type string by default.
+
+Next, define a getter method in user model class that returns the key.
+
+```c++
+User User::getByIdentityKey(const QString &username)
+{
+ TSqlORMapper mapper;
+ TCriteria cri(UserObject::Username, username);
+ return User(mapper.findFirst(cri));
+}
+```
+
+In the controller, use the following code:
+
+```c++
+QString username = identityKeyOfLoginUser();
+User loginUser = User::getByIdentityKey(username);
+```
+
+### Additional Comment
+
+The implementations of login that are described here in this chapter all using the session. Therefore, the lifetime of the session will be simultaneously the lifetime of the login.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/cache.md b/docs/de/user-guide/helper-reference/cache.md
new file mode 100644
index 000000000..c0ebe432b
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/cache.md
@@ -0,0 +1,71 @@
+---
+title: Cache
+page_id: "080.035"
+---
+
+## Cache
+
+In a Web application, every time a user requests, a process such as querying the database and rendering a template is performed to generate HTML data. Many requests have little overhead, but large sites receiving a large number of requests might not be able to ignore them. You don't want to do a lot of work that takes a few seconds, even on a small site. In such a case, the processed data is cached, and the cached data can be reused when the same request is received. Caching leads to a reduction in overhead, and you can expect a quick response.
+
+However, there is also the danger that old data will continue to be showed by reusing cached data. When data is updated, you need to consider how to handle its associated cached data. Do you need to update the cached data immediately, or is it OK to keep showing old data until the timeout expires? Consider the implementation depending on the nature of the data showed.
+
+Be careful when using cache on sites that have different pages for each user, for example, pages that display private information. If you cache page data, cache the data using a different string for each user as a key. If the key strings are not set uniquely, pages of other unrelated users will be displayed. Alternatively, when caching in such cases, it may be safe and effective to limit the data to common data for all users.
+
+
+## Enable cache module
+
+Uncomment the Cache.SettingsFile in the application.ini file, and set the value of the cache backend parameter 'Cache.Backend'.
+```
+Cache.SettingsFile=cache.ini
+
+Cache.Backend=sqlite
+```
+In this example, set up SQLite. You can also configure MongoDB or Redis as other usable backends.
+
+Next, edit cache.ini and set the connection information to the database. By default, it looks like this. Edit as necessary.
+```
+[sqlite]
+DatabaseName=tmp/cachedb
+HostName=
+Port=
+UserName=
+Password=
+ConnectOptions=
+PostOpenStatements=PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000; PRAGMA synchronous=NORMAL; VACUUM;
+```
+
+If you set up MongoDB or Redis on the backend, set the connection information as appropriate.
+
+## Page caching
+
+Generated HTML data can be cached.
+
+To generate HTML data, the action name was specified for the render () function. To use the page cache, specify two parameters of a key and a time for the renderOnCache () function. To send cached HTML data, use the renderOnCache () function.
+
+As an example, to cache the HTML data of the "index" view with the key "index" for 10 seconds, and to do the cached HTML data, do the following:
+```
+ if (! renderOnCache("index")) {
+ :
+ : // get data..
+ :
+ renderAndCache("index", 10, "index");
+ }
+```
+
+If executed by the index action, the third argument "index" can be omitted.
+See the [API Reference](http://api-reference.treefrogframework.org/classTActionController.html){:target="_blank"} for details.
+
+## Data caching
+
+You may not want to cache only pages. Binaries and text can be cached.
+Use the TCache class to store, retrieve, and delete data.
+
+```
+ Tf::cache()->set("key", "value", 10);
+ :
+ :
+ auto data = Tf::cache()->get("key");
+ :
+```
+
+See [API Reference](http://api-reference.treefrogframework.org/classTCache.html){:target="_blank"} for other methods.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/file-upload.md b/docs/de/user-guide/helper-reference/file-upload.md
new file mode 100644
index 000000000..1da31d48f
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/file-upload.md
@@ -0,0 +1,75 @@
+---
+title: File Upload
+page_id: "080.010"
+---
+
+## File Upload
+
+In this chapter we will create a simple form for a file upload. The code example below is using ERB. By specifying *true* for the third argument of the formTag() method, a form will be generated as multipart/form-data.
+
+```
+<%== formTag(urla("upload"), Tf::Post, true) %>
+
+ File:
+
+
+
+
+
+```
+
+In this example, the destination of the file upload is the upload action in the same controller.
+
+The upload file that is being received in action can be renamed as well by using the following method:
+
+```c++
+TMultipartFormData &formdata = httpRequest().multipartFormData();
+formdata.renameUploadedFile("picture", "dest_path");
+```
+
+The uploaded file is treated as a temporary file. If you do rename the upload file, the file is automatically deleted after the action ends.
+The original file name can be obtained using the following method:
+
+```c++
+QString origname = formdata.originalFileName("picture");
+```
+
+It may not be much used, but you can get a temporary file name just after uploading by using the uploadedFilePath() method. Random file names have been attached to make sure that they do not overlap.
+
+```c++
+QString upfile = formdata.uploadedFilePath("picture");
+```
+
+## Upload a variable number of files
+
+TreeFrog Framework also supports uploading a variable number of files. You can upload a variable number files provided that you use the Javascript library. Here, I'll explain an easier way of uploading two files (or more).
+
+First we create a form as follows:
+
+```
+<%== formTag(urla("upload"), Tf::Post, true) %>
+
+ File1:
+ File2:
+
+
+
+
+
+```
+
+When creating an input tag with JavaScript dynamically, it is important to add "[]" at the end of the 'name' like name = "picture []".
+
+To receive the uploaded files in the upload action, you can access the two files through the TMimeEntity object as follows:
+
+```c++
+QList lst = httpRequest().multipartFormData().entityList( "picture[]" );
+for (QListIterator it(lst); it.hasNext(); ) {
+ TMimeEntity e = it.next();
+ QString oname = e.originalFileName(); // original name
+ e.renameUploadedFile("dst_path.."); // rename file
+ :
+}
+```
+
+Don't forget to use the Iterator here for that.
diff --git a/docs/de/user-guide/helper-reference/image-manipulation.md b/docs/de/user-guide/helper-reference/image-manipulation.md
new file mode 100644
index 000000000..4318f47b1
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/image-manipulation.md
@@ -0,0 +1,85 @@
+---
+title: Image Manipulation
+page_id: "080.070"
+---
+
+## Image Manipulation
+
+There are various libraries that are capable of image processing. If you need to do complicated image processing, you may need to use [OpenCV](http://opencv.org/){:target="_blank"}, but in this chapter I would like to explain about image manipulation using the Qt library. It's easy to use. Since Qt is the base library of the TreeFrog Framework, it is ready to provide a GUI tool kit including many useful functions for image processing.
+
+At first, it is necessary to activate the QtGUI module of the TreeFrog framework.
+For this purpose, let's recompile the framework.
+
+In the case of Linux / Mac OS X :
+
+```
+ $ ./configure --enable-gui-mod
+ $ cd src
+ $ make
+ $ sudo make install
+ $ cd ../tools
+ $ make
+ $ sudo make install
+```
+
+In the case of Windows :
+
+```
+ > configure --enable-debug --enable-gui-mod
+ > cd src
+ > nmake install
+ > cd ..\tools
+ > nmake install
+ > cd ..
+ > configure --enable-gui-mod
+ > cd src
+ > nmake install
+ > cd ..\tools
+ > nmake install
+```
+
+Next, this setting is also required for the Web application side. Edit the project file (.pro), add "gui" in the variable with the name *QT*.
+
+```
+ :
+ QT += network sql gui
+ :
+```
+
+In this setting, the app is built as a GUI application. For Linux, particularly, X Window System is required to implement the environment.If you cannot meet this requirement, it is recommended that you use OpenCV as your image processing library.
+
+## Resize the Image
+
+The following code is an example of how to save a JPEG image by converting to the QVGA size while keeping the aspect ratio:
+
+```c++
+QImage img = QImage("src.jpg").scaled(320, 240, Qt::KeepAspectRatio);
+img.save("qvga.jpg");
+```
+
+- In reality, use the absolute path as a the file path.
+
+Using this QImage class, you can convert while ignoring aspect ratio. Also you can convert to a different image format. Please see [Qt Document](https://doc.qt.io/qt-5/){:target="_blank"} for detail.
+
+## Rotation of the Image
+
+The following code is an example of rotating an image clockwise through 90 degrees.
+
+```c++
+QImage img("src.jpg");
+QImage rotatedImg = img.transformed(QMatrix().rotate(90.0));
+rotatedImg.save("rotated.jpg");
+```
+
+## Image Synthesis
+
+Let's superimpose two images. You can align the small image to the coordinates of the upper right corner in the big picture.
+
+```c++
+QImage background("back.jpg");
+QPainter painter(&background);
+painter.drawImage(0, 0, QImage("small.jpg"));
+background.save("composition.jpg");
+```
+
+You can then prepare a painter to the original image, and draw a different picture there.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/index.md b/docs/de/user-guide/helper-reference/index.md
new file mode 100644
index 000000000..4a7d25ea7
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/index.md
@@ -0,0 +1,19 @@
+---
+title: Helper Reference
+page_id: "080.0"
+---
+
+## Helper Reference
+
+An helper is a helping function or class to complement the treatment. In TreeFrog Framwork there are many helpers, so that by using them, code can be simple and easy to understand. The following helpers are examples of their kind:
+
+* User authentication
+* Form validation
+* Mailer (Sending mail)
+* Access to the upload file
+* Logging
+* Access control of users
+
+If you make a helper as a class, it can be basically a class without a state (as per object-oriented). In a class with a state, the general case is defined as a model since it persists in the DB.
+
+In addition, for a similar piece of logic which appears several times in the controller and the view, you should consider whether it is worth cutting it out as a helper. Please see [this chapter](/en/user-guide/helper-reference/making-original-helper.html){:target="_target"} if you want to create a helper on your own.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/logging.md b/docs/de/user-guide/helper-reference/logging.md
new file mode 100644
index 000000000..aba3f16cd
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/logging.md
@@ -0,0 +1,84 @@
+---
+title: Logging
+page_id: "080.050"
+---
+
+## Logging
+
+Your Web application will log four outputs as follow:
+
+
+
+| Log | File Name | Content |
+|--------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| App log | app.log | Logging of Web application. Developers output will be logged here. See below about the output method. |
+| Access log | access.log | Logging access from the browser. Including access to a static file. |
+| TreeFrog log | treefrog.log | Logging of the TreeFrog system. System outputs, such as errors, are logged here. |
+| Query log | query.log | Query log issued to the database. Specify the file name in the file value of SqlQueryLog in the configuration file. When stopping the output, flush it. Because there is overhead when the log is outputting. It is a good idea to stop the output when you operate a formal Web application. |
+
+
+
+## Output of the Application Log
+
+The application log is used for logging your Web application. There are several types of methods that you can use to output the application log:
+
+* tFatal()
+* tError()
+* tWarn()
+* tInfo()
+* tDebug()
+* tTrace()
+
+Arguments that can be passed here are the same as the printf-format of format string and a variable number. For example, like this:
+
+```c++
+tError("Invalid Parameter : value : %d", value);
+```
+
+Then, the following log will be output to the *log/app.log* file:
+
+```
+ 2011-04-01 21:06:04 ERROR [12345678] Invalid Parameter : value : -1
+```
+
+Line feed code is not required at the end of the format string.
+
+## Changing Log Layout
+
+It is possible to change the layout of the log output, by setting FileLogger.Layout parameters in the configuration file *logger.ini*.
+
+```ini
+# Specify the layout of FileLogger.
+# %d : date-time
+# %p : priority (lowercase)
+# %P : priority (uppercase)
+# %t : thread ID (dec)
+# %T : thread ID (hex)
+# %i : PID (dec)
+# %I : PID (hex)
+# %m : log message
+# %n : newline code
+FileLogger.Layout="%d %5P [%t] %m%n"
+```
+
+When a log was generated, date and time will be inserted there and tagged with '%d' in the log layout.
+The date format is specified in the FileLogger.DateTimeFormat parameter. The format that can be specified is the same value as the argument of QDateTime::toString(). Please refer to the [Qt document](http://doc.qt.io/qt-5/qdatetime.html){:target="_blank"} for further detail.
+
+```ini
+# Specify the date-time format of FileLogger, see also QDateTime
+# class reference.
+FileLogger.DateTimeFormat="yyyy-MM-dd hh:mm:ss"
+```
+
+## Changing the Logging Level
+
+You can set the log output level using the following parameter in *logger.ini*:
+
+```ini
+# Outputs the logs of equal or higher priority than this.
+FileLogger.Threshold=debug
+```
+
+In this example, the log level is higher than debug.
+
+##### In brief: Using the tDebug() function to output the debug log (necessary for development).
diff --git a/docs/de/user-guide/helper-reference/mailer.md b/docs/de/user-guide/helper-reference/mailer.md
new file mode 100644
index 000000000..ea50c57d1
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/mailer.md
@@ -0,0 +1,107 @@
+---
+title: Mailer
+page_id: "080.040"
+---
+
+## Mailer
+
+TreeFrog Framework incorporates a mailer (mail client) which makes it possible to send mails by SMTP. For now (v1.0), only SMTP message sending is possible. To create mail messages, an ERB template is used.
+
+First, let's create a mail skeleton with the following command:
+
+```
+ $ tspawn mailer information send
+ created controllers/informationmailer.h
+ created controllers/informationmailer.cpp
+ created controllers/controllers.pro
+ created views/mailer/mail.erb
+```
+
+The class of InformationMailer is created in the controller directory, and the template with the name *mail.erb* is created in the views directory.
+
+Next, open the *mail.erb* that was previously created and then change its content to the following:
+
+```
+ Subject: Test Mail
+ To: <%==$ to %>
+ From: foo@example.com
+
+ Hi,
+ This is a test mail.
+```
+
+Above the blank line is the mail header, and below is the content of the body. Specify subject and destination in the header. It is possible to add any field of header. However, Content-Type and Date field are automatically added, so that you don't need to write them there.
+
+If you are using multi-byte characters, such as Japanese, save the file by setting the encoding (default UTF-8) in the settings file of InternalEncoding.
+
+Call the deliver() method at the end of the send() method of the InformationMailer class.
+
+```c++
+void InformationMailer::send()
+{
+ QString to = "sample@example.com";
+ texport(to);
+ deliver("mail"); // ← mail.erb Mail sent by template
+}
+```
+
+You are now able to call from outside of the class. By writing the following code in the action, the process of mail sending will be executed:
+
+```c++
+InformationMailer().send();
+```
+
+- When you actually send a mail, please see the following "SMTP Settings" section.
+
+When you need to send a mail directly without using a template, you can use the TSmtpMailer::send() method.
+
+## SMTP Settings
+
+There is no configuration information for SMTP in the code above. It becomes necessary to set information about SMTP in the *application.ini* file.
+
+```ini
+# Specify the connection's host name or IP address.
+ActionMailer.smtp.HostName=smtp.example.com
+
+# Specify the connection's port number.
+ActionMailer.smtp.Port=25
+
+# Enables SMTP authentication if true; disables SMTP
+# authentication if false.
+ActionMailer.smtp.Authentication=false
+
+# Specify the user name for SMTP authentication.
+ActionMailer.smtp.UserName=
+
+# Specify the password for SMTP authentication.
+ActionMailer.smtp.Password=
+
+# Enables the delayed delivery of email if true. If enabled, deliver() method
+# only adds the email to the queue and therefore the method doesn't block.
+ActionMailer.smtp.DelayedDelivery=false
+```
+
+If you use SMTP authentication, you need to set this:
+
+```ini
+ActionMailer.smtp.Authentication=true
+```
+
+As for the authentication method, CRAM-MD5, LOGIN and PLAIN (using this priority) are mounted in a way, so that the authentication process is performed automatically.
+
+In this framework, SMTPS email sending is not supported.
+
+## Delay sending the mail
+
+Since mail sending by SMTP needs to pass the data through an external server, it requires time compared to the process. You can return an HTTP response before the mail sending process is executed.
+
+Edit the *application.ini* file as follows:
+
+```ini
+ActionMailer.smtp.DelayedDelivery=true
+```
+
+By doing this, the deliver() method will be a non-blocking function of merely queuing data. The mail sending process will occur after returning an HTTP response.
+
+**Additional note:**
+If you don't set the delay sending (in case of *false*), the deliver() method would keep blocking until the SMTP processing ends, or all ends up in an error.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/making-original-helper.md b/docs/de/user-guide/helper-reference/making-original-helper.md
new file mode 100644
index 000000000..bf3de536c
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/making-original-helper.md
@@ -0,0 +1,26 @@
+---
+title: Making Original Helper
+page_id: "080.090"
+---
+
+## Making Original Helper
+
+When you create a helper, it can be accessible from the model/controller/view. Please try to consider making a helper whenever similar code appears several times.
+
+## How to Make the helper
+
+You can implement the class as you like in the *helpers* directory, remember to put the charm of T_HELPER_EXPORT. Other than that you can do anything.
+
+```c++
+#include
+class T_HELPER_EXPORT SampleHelper
+{
+ // Write as you like.
+};
+```
+
+Add the header and the source file to project files, *helpers.pro*, then run make.
+
+## How to Use the Helper
+
+Use it the same way as a normal class by including a header file. There is no particular difference compared to the way the normal class is used.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/pagination.md b/docs/de/user-guide/helper-reference/pagination.md
new file mode 100644
index 000000000..478dd1406
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/pagination.md
@@ -0,0 +1,75 @@
+---
+title: Pagination
+page_id: "080.080"
+---
+
+## Pagination
+
+When data cannot be displayed on one single Web page, you might have already heard about **pagination** or **paging**. TreeFrog provides such a function which divides into multiple Web pages. This technique is very common for many web applications on the internet.
+
+TreeFrog provides a class for pagination with very basic functions. In order to use TreeFrog's pagination ability you need to use the *TPaginator* class. The following example - written in ERB, but similar to Otama - will show you how to use pagination.
+
+First of all, in the action of the *controller* class we will retrieve information about the current displaying page number by using query arguments. Then we get a list of models that correspond to that page number and pass them to the view.
+
+```c++
+int current = httpRequest().queryItemValue("page", "1").toInt();
+int totalCount = Blog::count();
+
+// Display up to ten items per page. The argument '5' specifies the number of pages
+// to show ‘around’ the current page on a pagination bar, and should be an odd number
+TPaginator pager(totalCount, 10, 5);
+pager.setCurrentPage(current); // Set the page number that is supposed to be displayed
+texport(pager);
+
+// Obtain the corresponding items and add them to the view
+QList blogList = Blog::getBlogs( pager.itemCountPerPage(), pager.offset() );
+texport(blogList);
+render();
+```
+
+Now, let's have a look at the view.
+It is a good technique to use a partial template when you want to display page numbers.
+In the following example, we used the passed *TPaginator* object to draw the page numbers and their respective links. For each link, the *urlq()* method creates the URL and the specified query arguments to the current action for you.
+
+Using template: views/partial/pagination.erb
+
+```
+<%#include %>
+<% tfetch(TPaginator, pager); %>
+
+
+```
+
+Rendering a partial template is rather simple. Use the following *renderPartial()* method to achieve this:
+
+```
+<%== renderPartial("pagination") %>
+```
+
+The passing argument "pagination" is the name of the template you want to include. Furthermore, this template draws a list of models passed from the controller. For more details about rendering templates, please refer to the [generator](/en//user-guide/generator/index.html){:target="_blank"} which generates templates such as *index*, *show* etc.
+
+Next is the acquisition of the model.
+To obtain a list of applicable models, you can issue a query with the LIMIT and OFFSET parameters from the database. Depending on your requirements, you may need to specify a WHERE or to sort the obtaining models.
+
+Because such SQL queries are commonly used, the following TreeFrog Framework utility function requires not much code.
+
+```c++
+QList Blog::getBlogs(int limit, int offset)
+{
+ return tfGetModelListByCriteria(TCriteria(), limit, offset);
+}
+```
+
+Please refer the [API Reference](http://treefrogframework.org/tf_doxygen/tmodelutil_8h.html){:target="_blank"} page for more details about the model utility.
+
+**Note:**
+Since pagination is not that difficult, you can also try to challenge the implementation without using the TPaginator class at all.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/plugin.md b/docs/de/user-guide/helper-reference/plugin.md
new file mode 100644
index 000000000..10f289b81
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/plugin.md
@@ -0,0 +1,132 @@
+---
+title: Plugin
+page_id: "080.060"
+---
+
+## Plugin
+
+In TreeFrog, the plug-in refers to dynamic libraries (shared library, DLL) that are added to extend the functionality. Since TreeFrog has the Qt plug-in system, you can make a new plug-in, if the standard function is insufficient. At this point, the categories of possible plug-ins that can be made are as follows:
+
+* Logger plug-in (for log output)
+* The session store plug-in (for Saving and reading sessions)
+
+## How to Create a Plug-in
+
+Create a plug-in is exactly the same as how to create a plug-in for Qt. To demonstrate this, let's create a logger plug-in. First, we'll create a working directory in the *plugin* directory
+
+```
+ > cd plugin
+ > mkdir sample
+```
+
+- Basically, you can choose any place for the working directory, but when thinking about the path solution, it is a good idea to create the working directory as just previously mentioned above.
+
+We'll create a plug-in wrapper class (TLoggerPlugin in this example). We do this by inheriting the class as an interface and then we override some of the virtual functions.
+
+```c++
+sampleplugin.h
+---
+class SamplePlugin : public TLoggerPlugin
+{
+ QStringList keys() const;
+ TLogger *create(const QString &key);
+};
+```
+
+In the keys() method, the string that can be the key for supporting the plug-in, is returned as a list. In the create() method, the instance of the logger that corresponds to the key is created and implemented in a way to be returned as a pointer.
+
+After including the QtPlugin in the source file, you can register the plug-in by putting a macro, such as the following:
+
+* The first argument can be any string such as the name of the plug-in
+* The second argument is a plug-in class name.
+
+```c++
+sampleplugin.cpp
+---
+#include
+ :
+ :
+Q_EXPORT_PLUGIN2(samplePlugin, SamplePlugin)
+```
+
+Next, we create a function to extend the plug-in (class). We'll make a logger that outputs a log here. As above, we do this by inheriting the TLogger class as an interface from logger and then override some virtual functions again.
+
+```c++
+samplelogger.h
+---
+class SampleLogger : public TLogger
+{
+public:
+ QString key() const { return "Sample"; }
+ bool isMultiProcessSafe() const;
+ bool open();
+ void close();
+ bool isOpen() const;
+ void log(const TLog &log);
+ ...
+};
+```
+
+Our next target is the project file (.pro). Do not forget to add the value "plugin" to the CONFIG parameter in this file!
+
+```
+TARGET = sampleplugin
+TEMPLATE = lib
+CONFIG += plugin
+DESTDIR = ..
+include(../../appbase.pri)
+HEADERS = sampleplugin.h \
+ samplelogger.h
+SOURCES = sampleplugin.cpp \
+ samplelogger.cpp
+```
+
+- It is important to include the *appbase.pri* file by using the include function.
+
+After this, when you build you can make plug-ins that are dynamically loadable. Save the plug-in to the plugin directory every time without fault, because the application server (AP server) loads the plug-ins from this directory.
+Please see the Qt documentation for more details of the [plug-in system](http://doc.qt.io/qt-5/plugins-howto.html){:target="_blank"}.
+
+## Logger Plug-in
+
+FileLogger is a basic logger that outputs the log inside a file. However, it may be insufficient depending on the requirements. For example, if a log is used to save as a database or as a log file that you want to keep by rotation, you may want to extend the functionality using the mechanism of the plug-in.
+
+As described above, after creating a logger plug-in, place the plug-in in the plug-in directory. Furthermore, update the configuration information inside the *logger.ini* file in order to be loaded into the application server. Arrange the keys of the logger in the *loggers* parameter with spaces. The following example shows how this may look like:
+
+```
+ Loggers=FileLogger Sample
+```
+
+In this way, the plug-in will be loaded when you start the application server.
+
+Once again, the plug-in interface for the logger is a class as shown next:
+
+* Plug-in interface: TLoggerPlugin
+* Logger interface: TLogger
+
+### About the Logger Methods
+
+In order to implement the logger, you can override the following methods in the class TLogger:
+
+* key(): returns the name of the logger.
+* open(): open of the log called by the plug-in immediately after loading.
+* close(): close the log.
+* log(): output the log. This method may be called from multiple threads, make this as **thread-safe**.
+* isMultiProcessSafe(): indicates whether it is safe for you to output a log in a multi-process. When it is safe, it returns true. I not, it returns as false.
+
+About MultiProcessSafe method: when it returns *false* (meaning it is not safe) and the application server is running in a multiprocess mode as well, the isMultiProcessSafe() method calls open()/close() each time before and after it is logging output (leads into increasing overhead).
+By the way, this system has lock/unlock around this by semaphore, so that there is no conflict. And when you return *true*, the system will only call the open() method first.
+
+## Session Store Plug-in
+
+The session store that is standard on TreeFrog is as follows:
+
+* Cookies Session: save to cookies
+* DB session: save to DB. You need to make the table only for this purpose.
+* File session: save to file
+
+If these are insufficient, you can create a plug-in that inherits the interface class.
+
+* Plug-in interface: TSessionStorePlugin
+* Session Store interface: TSessionStore
+
+In the same manner as described above, by overriding the virtual function by inheriting these classes, you can create a plug-in. Then in order to load this plug-in, you can set only one key at *Session.StoreType* parameter in the *application.ini* file (you can choose only one). The default is set as cookie.
\ No newline at end of file
diff --git a/docs/de/user-guide/helper-reference/validation.md b/docs/de/user-guide/helper-reference/validation.md
new file mode 100644
index 000000000..0d149db19
--- /dev/null
+++ b/docs/de/user-guide/helper-reference/validation.md
@@ -0,0 +1,115 @@
+---
+title: Validation
+page_id: "080.030"
+---
+
+## Validation
+
+Sometimes, data that is sent as a request may not have the format that the developer has specified. For example, some users might put letters where numbers are required. Even if you have implemented Javascript to validate on the client side, tampering with the content of a request is not complicated, so a server side system for validating content is essential.
+
+As mentioned in the [controller chapter]({{ site.baseurl }}/en/user-guide/controller/index.html){:target="_blank"}, data in received requests is expressed as hash format. Usually before sending the request data to the model, each value should be validated the value's format.
+
+First, we will generate a validation class skeleton for validating request data (hash) for *blog*. Navigate to the application root directory and then execute the following commands.
+
+```
+ $ tspawn validator blog
+ created helpers/blogvalidator.h
+ created helpers/blogvalidator.cpp
+ updated helpers/helpers.pro
+```
+
+The validation rules are set in the construction of the generated BlogValidator class. The following example shows the implementation of a the rule for the title variable which must be made of at least 4 or more letters and must not have more than 20.
+
+```c++
+BlogValidator::BlogValidator() : TFormValidator()
+{
+ setRule("title", Tf::MinLength, 4);
+ setRule("title", Tf::MaxLength, 20);
+}
+```
+
+The enum value is the second argument. You can specify mandatory input, maximum/minimum string length, integer of maximum/minimum value, date format, e-mail address format, user-defined rules (regular expression), and so on (defined in tfnamespace.h).
+
+There is also a fourth argument: setRule(). This sets the validation error message. If you don't specify a message (what we have done here), the message defined in *config/validation.ini* file is used.
+
+Rules are implicitly set for "mandatory input". If you do NOT want an input to be "mandatory", describe the validation rule as follows:
+
+```c++
+setRule("title", Tf::Required, false);
+```
+
+
+
+**Rules**
+
+
+
+
+
+| enum | Meaning |
+|--------------|-------------------------|
+| Required | Input required |
+| MaxLength | Maximum length |
+| MinLength | Minimum length |
+| IntMax | Maximum value (integer) |
+| IntMin | Minimum value (integer) |
+| DoubleMax | Maximum value (double) |
+| DoubleMin | Minimum value (double) |
+| EmailAddress | Email address format |
+| Url | URL format |
+| Date | Date format |
+| Time | Time format |
+| DateTime | DateTime format |
+| Pattern | Regular Expressions |
+
+
+
+Once you have set the rules, you can use them in the controller. Include the header file relating to this.
+The following code example validates the request data that is retrieved from the form. If you get a validation error, you get the error message.
+
+```c++
+QVariantMap blog = httpRequest().formItems("blog");
+BlogValidator validator;
+if (!validator.validate(blog)) {
+ // Retrieve message rules for validation error
+ QStringList errs = validator.errorMessages();
+ :
+}
+```
+
+Normally, since there are sets of multiple rules, there will also be multiple error messages. One-by-one processing is a little cumbersome. However, if you use the following method, you can export the all validation error messages at once (to be passed to the view):
+
+```c++
+exportValidationErrors(valid, "err_");
+```
+
+In the second argument, specify a prefix as the variable name for the export object.
+
+##### In brief: Set rules for the form data and validate them by using validate().
+
+## Custom validation
+
+The explanation above is about static validation. It cannot be used in a dynamic case where the allowable range of the value changes according to what the value is. In this case, you may override the validate() method and then you can write any code of validation whatsoever.
+
+The following code is an example on how a customized validation could look like:
+
+```c++
+bool FooValidator::validate(const QVariantMap &hash)
+{
+ bool ret = THashValidator::validate(hash); // ←Validation of static rules
+ if (ret) {
+ QDate startDate = hash.value("startDate").toDate();
+ QDate endDate = hash.value("endDate").toDate();
+
+ if (endDate < startDate) {
+ setValidationError("error");
+ return false;
+ }
+ :
+ :
+ }
+ return ret;
+}
+```
+
+It compares the value of *endData* and the value of *startDate*. If the endDate is smaller than the startDate, an validation error will be thrown.
\ No newline at end of file
diff --git a/docs/de/user-guide/index.md b/docs/de/user-guide/index.md
new file mode 100644
index 000000000..aa7d8750e
--- /dev/null
+++ b/docs/de/user-guide/index.md
@@ -0,0 +1,5 @@
+---
+title: Document Index
+layout: docindex
+---
+
diff --git a/docs/de/user-guide/install/index.md b/docs/de/user-guide/install/index.md
new file mode 100644
index 000000000..62e1a33be
--- /dev/null
+++ b/docs/de/user-guide/install/index.md
@@ -0,0 +1,166 @@
+---
+title: Install
+page_id: "020.0"
+---
+
+## Install
+
+First of all, we need to install the Qt library in advance.
+
+On Windows and macOS, download the package from the [Qt site](http://qt-project.org/downloads){:target="_blank"} and install it.
+On Linux, you can install a package for each distribution.
+
+In case of Ubuntu:
+Install the Qt libraries and dev tools:
+
+```
+ $ sudo apt-get install -y qt5-default qt5-qmake libqt5sql5-mysql libqt5sql5-psql
+ libqt5sql5-odbc libqt5sql5-sqlite libqt5core5a libqt5qml5 libqt5xml5 qtbase5-dev
+ qtdeclarative5-dev qtbase5-dev-tools gcc g++ make cmake
+```
+
+Now install the DB client libraries:
+
+```
+ $ sudo apt-get install -y libmysqlclient-dev libpq5 libodbc1 libmongoc-dev libbson-dev
+```
+
+### Installation Instructions
+
+1. Extract the file you just have [downloaded](http://www.treefrogframework.org/en/download/){:target="_blank"}.
+
+ The following command applies to version 'x.x.x'. Please update it appropriately.
+
+ ```
+ $ tar xvfz treefrog-x.x.x.tar.gz
+ ```
+
+2. Run build commands.
+
+ In Windows:
+ Please create a binary of two types for *release* and for *debugging*.
+ Start the Qt Command Prompt and then build with the following commands. The configuration batch should be run twice.
+
+ ```
+ > cd treefrog-x.x.x
+ > configure --enable-debug
+ > cd src
+ > nmake install
+ > cd ..\tools
+ > nmake install
+ > cd ..
+ > configure
+ > cd src
+ > nmake install
+ > cd ..\tools
+ > nmake install
+ ```
+
+ In UNIX-based OS Linux, and macOS:
+ Enter the following command from the command line:
+
+ ```
+ $ cd treefrog-x.x.x
+ $ ./configure
+ $ cd src
+ $ make
+ $ sudo make install
+ $ cd ../tools
+ $ make
+ $ sudo make install
+ ```
+
+ **Note:**
+ In order to debug the TreeFrog Framework itself, please use the *configure* option.
+ Now please run this command:
+
+ ```
+ ./configure --enable-debug
+ ```
+
+ The next command updates the dynamic linker runtime bindings in Linux only.
+
+ ```
+ $ sudo ldconfig
+ ```
+
+3. Create a shortcut of TreeFrog Command Prompt (Windows only).
+ Right-click on the folder on which you want to create a shortcut and select "New" and then click the "Shortcut". Set the links as follows:
+
+ ```
+ C:\Windows\System32\cmd.exe /K C:\TreeFrog\x.x.x\bin\tfenv.bat
+ ```
+
+ ('x.x.x' represents the current version you use)
+
+
+
+### Configure Option
+
+By specifying various options, you can customize to suit your environment.
+
+Options available on Windows using "Configure option":
+
+```
+ > configure --help
+ Usage: configure [OPTION]... [VAR=VALUE]...
+ Configuration:
+ -h, --help display this help and exit
+ --enable-debug compile with debugging information
+ --enable-gui-mod compile and link with QtGui module
+ --enable-mongo compile with MongoDB driver library
+
+ Installation directories:
+ --prefix=PREFIX install files in PREFIX [C:\TreeFrog\x.x.x]
+```
+
+Options available on Linux, and UNIX-like OS:
+
+```
+ $ ./configure --help
+ Usage: ./configure [OPTION]... [VAR=VALUE]...
+ Configuration:
+ -h, --help display this help and exit
+ --enable-debug compile with debugging information
+ --enable-gui-mod compile and link with QtGui module
+ --enable-mongo compile with MongoDB driver library
+ --spec=SPEC use SPEC as QMAKESPEC
+
+ Installation directories:
+ --prefix=PREFIX install files in PREFIX [/usr]
+
+ Fine tuning of the installation directories:
+ --bindir=DIR user executables [/usr/bin]
+ --libdir=DIR object code libraries [/usr/lib]
+ --includedir=DIR C header files [/usr/include/treefrog]
+ --datadir=DIR read-only architecture-independent data [/usr/share/treefrog]
+```
+
+Options available in macOS:
+
+```
+ $ ./configure --help
+ Usage: ./configure [OPTION]... [VAR=VALUE]...
+ Configuration:
+ -h, --help display this help and exit
+ --enable-debug compile with debugging information
+ --enable-gui-mod compile and link with QtGui module
+ --enable-mongo compile with MongoDB driver library
+
+ Fine tuning of the installation directories:
+ --framework=PREFIX install framework files in PREFIX [/Library/Frameworks]
+ --bindir=DIR user executables [/usr/bin]
+ --datadir=DIR read-only architecture-independent data [/usr/share/treefrog
+```
diff --git a/docs/de/user-guide/introduction/index.md b/docs/de/user-guide/introduction/index.md
new file mode 100644
index 000000000..83d82066c
--- /dev/null
+++ b/docs/de/user-guide/introduction/index.md
@@ -0,0 +1,40 @@
+---
+title: Introduction
+page_id: "010.0"
+---
+
+## Introduction
+
+### What is the TreeFrog Framework
+
+TreeFrog Framework is a full-stack Web application framework. Written in C++, it is lightweight (low resource demands), and allows extremely fast working.
+
+With the aim of reducing development costs while producing a C++ framework, a policy of "convention over configuration" has been followed. The configuration file has been made as small as possible. Because it provides help in automatic generation of code for template systems (scaffolding), O/R mapping and ORM, developers are free to focus on logic.
+
+### Cross-platform
+
+TreeFrog Framework is cross-platform. It runs on Windows, of course, but also on UNIX-like Operating Systems, macOS, and Linux. Using Windows open-source coding, it is possible to support Linux. Web applications that run on multiple platforms are also possible, simply by recompiling the source code.
+
+### Controller
+
+Developers will be easily able to obtain the data representing HTTP request/response, and the session. In addition to this, it has already provided same useful rough features such as login authentication, form validation, and access control.
+Also, because it provides a mechanism (routing system) for call methods by the appropriate controller from the requested URL to required actions, there is no need to write rules one-by-one in the configuration file, or to distribute any action requests.
+
+### View
+
+In the view layer, ERB format descriptions, well known in Rails, may be used. The C++ code <% …%> can be embedded in HTML files. This means that coding can be written in a way very similar to a scripting language.
+It also offers a new template system (Otama) that completely separates the presentation logic from the templates. Being written in pure HTML, the template is able to describe the C++ coded logic file. This enables programmers and designers to collaborate.
+
+### Model
+
+In the model layer, called SqlObject, an O/R mapper (O/R mapping system) is provided. App developers will therefore be able to focus on developing business logic without having to write too much because of this SQL.
+However, that being said, if data needs to be used in complex conditions, SQL can be readily utilized. Through the use of placeholders, SQL queries may be run easily and safely.
+In addition, this framework is compatible with all major database programs such as MySQL, PostgreSQL, SQLite, DB2, and Oracle.
+
+### Qt-based
+
+Qt and the TreeFrog Framework are linked. Not only is the Qt GUI framework powerful, but the non-GUI functionality is also very good. By combining Web applications for the core module container class, network, SQL, JSON, unit test, and meta-object, app developers are provided with very convenient usability features.
+
+### Open source
+
+TreeFrog Framework is open-source software, under the new BSD license (3-clause BSD License).
\ No newline at end of file
diff --git a/docs/de/user-guide/introduction/license.md b/docs/de/user-guide/introduction/license.md
new file mode 100644
index 000000000..174a79a3e
--- /dev/null
+++ b/docs/de/user-guide/introduction/license.md
@@ -0,0 +1,31 @@
+---
+title: License
+page_id: "010.020"
+---
+
+## License
+
+### Modified BSD license (New BSD License)
+
+Modification, distribution or copying of source code is allowed in accordance with the license conditions below. If you modify the source code, you don't need to publish it; you can select "not publish" if you wish.
+
+Copyright (c) 2010-2022, AOYAMA Kazuharu
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+* Neither the name of the TreeFrog Framework Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/docs/de/user-guide/introduction/requirements.md b/docs/de/user-guide/introduction/requirements.md
new file mode 100644
index 000000000..d200ab082
--- /dev/null
+++ b/docs/de/user-guide/introduction/requirements.md
@@ -0,0 +1,21 @@
+---
+title: Requirements
+page_id: "010.010"
+---
+
+## Requirements
+
+### Execution environment
+
+* Windows, Linux, UNIX-like OS or maxOS
+* Qt version 5.4 or later – [The Qt Company](https://www.qt.io/)
+
+### Development environment
+
+In order to develop a Web application in TreeFrog Framework, you must have C++ development tools appropriate to the execution environment as lsited above. For the time being, development is possible using the g++ compiler to make and edit commands.
+
+Visual Studio is available for Windows but MinGW is not supported. Using the Qt Creator IDE is also a good idea.
+
+On maxOS, if you install Xcode, various commands such as a compiler are installed. For Linux, I recommend installing the packages that are provided with the distribution.
+
+For debugging, using the Qt Creator is a safe choice, because it is a framework based on Qt.
diff --git a/docs/de/user-guide/model/access-mongodb.md b/docs/de/user-guide/model/access-mongodb.md
new file mode 100644
index 000000000..fa412dd53
--- /dev/null
+++ b/docs/de/user-guide/model/access-mongodb.md
@@ -0,0 +1,206 @@
+---
+title: Access MongoDB
+page_id: "060.050"
+---
+
+## Access MongoDB
+
+MongoDB is a document-oriented open source database. It is one of the so-called NoSQL systems.
+
+To manage the data in the RDB, you need to define a table (schema) in advance, but you will most likely not need to do that with MongoDB. In MongoDB, data is represented by a like JSON format (BSON) called "Documents", and the set is managed as a "collection". Each document has assigned a unique ID (ObjectID) by the system.
+
+Here is a comparison between the layered structures of an RDB and MongoDB.
+
+
+
+| MongoDB | RDB | Remarks |
+|------------|----------|---------------|
+| Database | Database | The same term |
+| Collection | Table | |
+| Document | Record | |
+
+
+
+## Installation
+
+Re-install the framework with the following command:
+
+```
+ $ tar xvzf treefrog-x.x.x.tar.gz
+ $ cd treefrog-x.x.x
+ $ ./configure --enable-mongo
+ $ cd src
+ $ make
+ $ sudo make install
+ $ cd ../tools
+ $ make
+ $ sudo make install
+```
+
+- x.x.x represents the current version you have downloaded.
+
+## Setting Credentials
+
+Assume that MongoDB has being installed and the server is running. Then you can make a skeleton of the application in the generator.
+
+Let's set the connection information in order to communicate with the MongoDB server. First, edit the following line in *config/application.ini*.
+
+```ini
+ MongoDbSettingsFile=mongodb.ini
+```
+
+Then edit the *config/mongodb.ini*, specifying the host name and database name. As for the configuration file for the SQL database, this file is divided into three sections, *dev*, *test*, and *product*.
+
+```ini
+ [dev]
+ DatabaseName=foodb # Database name
+ HostName=192.168.x.x # Host name or IP address
+ Port=
+ UserName=
+ Password=
+ ConnectOptions= # unused
+```
+
+Now, let's check the settings by execute the following command in the application root directory *when MongoDB is running*:
+
+```
+ $ tspawn --show-collections
+ DatabaseName: foodb
+ HostName: localhost
+ MongoDB opened successfully
+ -----------------
+ Existing collections:
+```
+
+If it succeeds, it will be displayed like above.
+
+Web applications can access both MongoDB and SQL databases. This enables the Web application to respond in a flexible way in case of an increased load on the Web system.
+
+## Creating New Document
+
+To access the MongoDB server, use the *TMongoQuery* object. Specify the collection name as an argument to the constructor to create an instance.
+
+MongoDB document is represented by a QVariantMap object. Set the key-value pair for the object and then insert it by using the insert() method into the MongoDB at the end.
+
+```c++
+#include
+---
+TMongoQuery mongo("blog"); // Operations on a blog collection
+QVariantMap doc;
+
+doc["title"] = "Hello";
+doc["body"] = "Hello world.";
+mongo.insert(doc); // Inserts new
+```
+
+Internally, a unique ObjectID is allocated when the insert() method is being called.
+
+### Supplement
+
+As this example shows, there is no need for developers to worry at all about the process of connect/disconnect with MongoDB, because the management of the connection is handled by the framework itself. Through the mechanism of re-using connections, the overhead caused by the number of connections/disconnections is kept low.
+
+## Reading the Document
+
+When you search for documents and some of them (or all) match the previously set criteria, it is necessary to pass the returned documents (if any) one by one into a QVariantMap. Please be ware, that we have to use QVariantMap here, because the search criteria is expressed as QVariantMap, too.
+
+The following example creates an Criteria object which contains two criteria sets and then being passed as an argument to the find() method. Assuming that there is more than one document that matches the search criteria we use the *while* statement to loop through the list of available documents.
+
+```c++
+TMongoQuery mongo("blog");
+QVariantMap criteria;
+
+criteria["title"] = "foo"; // Set the search criteria
+criteria["body"] = "bar"; // Set the search criteria
+
+mongo.find(criteria); // Run the search
+while (mongo.next()) {
+ QVariantMap doc = mongo.value(); // Get a document
+ // Do something
+}
+```
+
+- Two criteria are joined by the AND operator.
+
+If you are looking for only one documents that matches the criteria, you can use the findOne() method.
+
+```c++
+QVariantMap doc = mongo.findOne(criteria);
+```
+
+The following example sets an criteria for a 'num'. Only documents those value 'num' is greater than 10 will match. In order to achieve this, use **$gt** as the comparison operator for your criteria object.
+
+```c++
+QVariantMap criteria;
+QVariantMap gt;
+gt.insert("$gt", 10);
+criteria.insert("num", gt); // Set the search criteria
+mongo.find(criteria); // Run the search
+ :
+```
+
+**Comparison Operators:**
+
+* **$gt**: Greater than
+* **$gte**: Greater than or equal to
+* **$lt**: Less than
+* **$lte**: Less than or equal to
+* **$ne**: Not equal
+* **$in**: In
+* **$nin**: Not in
+
+### OR Operator
+
+Joins query clauses with a logical OR **$or** operator.
+
+```c++
+QVariantMap criteria;
+QVariantList orlst;
+orlst << c1 << c2 << c3; // Three criteria
+criteria.insert("$or", orlst);
+ :
+```
+
+As described above, the search condition in *TMongoQuery* is represented by an object from type *QVariantMap*. In MongoDB, the search condition is represented by JSON, so when executing a query, the QVariantMap object will be converted to a JSON object. Therefore you can specify all the operators supported by MongoDB provided that you have described them properly according to their rules. An efficient search will be then possible.
+
+There are more operators provided by MongoDB. Please have a look at the [MongoDB documents](http://docs.mongodb.org/manual/reference/operator/nav-query/){:target="_blank"} for an insight view.
+
+## Updating a Document
+
+We will read a document from the MongoDB server and then update it. As indicated by the update() method, we will update one document that matches the criteria.
+
+```c++
+TMongoQuery mongo("blog");
+QVariantMap criteria;
+criteria["title"] = "foo"; // Set the search criteria
+QVariantMap doc = mongo.findOne(criteria); // Get one
+doc["body"] = "bar baz"; // Change the contents of the document
+
+criteria["_id"] = doc["_id"]; // Set ObjectID to the search criteria
+mongo.update(criteria, doc);
+```
+
+It is important to note here, that even if there are several documents matching the search criteria, but in order to be sure the the document can be updated, add the *ObjectID* to the search criteria.
+
+In addition, if you want to update all documents that match the criteria, you can use the updateMulti() method.
+
+```c++
+mongo.updateMulti(criteria, doc);
+```
+
+## Removing a Document
+
+Specify the object ID as a condition If you want to delete one document.
+
+```c++
+criteria["_id"] = "517b4909c6efa89aed288706"; // Removes by ObjectID
+mongo.remove(criteria);
+```
+
+You can also remove all documents that match the criteria.
+
+```c++
+TMongoQuery mongo("blog");
+QVariantMap criteria;
+criteria["foo"] = "bar";
+mongo.remove(criteria); // Remove
+```
diff --git a/docs/de/user-guide/model/index.md b/docs/de/user-guide/model/index.md
new file mode 100644
index 000000000..80adc7a05
--- /dev/null
+++ b/docs/de/user-guide/model/index.md
@@ -0,0 +1,113 @@
+---
+title: Model
+page_id: "060.0"
+---
+
+## Model
+
+The model is an object that represents the (abstract) information that should be returned to the browser. In fact it is not so simple in terms of business logic. So, let's try to understand it.
+
+Models are stored in a system or in an external database in a persistent state. Looking from the controller side, regardless of the model, you are accessing a database for information wanted for the HTTP response. Once the information has been left in a persistent state in the database, you will be able to get a model with information that you can pass to the view.
+
+When you write directly to SQL to access the database, coding tends to become complicated in some cases and therefore more difficult to read. This is even truer if the DB schema becomes complicated. In order to mitigate this is difficulty, TreeFrog is equipped with an O/R mapping system (named SqlObject).
+
+In a Web application, CRUD (create, read, update, delete) is a set of functions with minimum requirements; the SQL statement you write is almost routine. For this part, the O/R mapping system will be working here very effective.
+
+I personally think, as for the Web frameworks, it is recommended to have the model object itself related to an object for O/R mapping (these objects will be referred as ORM objects). By default, each model object in TreeFrog Framework includes ORM objects.
+
+ "A model has ORM object(s)."
+
+Doing it this way is beneficial in a number of ways:
+
+* Intuitive structure of the ORM class.
+* Possible to conceal the information that is not required to show on the controller side.
+* Can absorb both logical delete and physical delete of the record as a model.
+ → Use this page to create a deletion flag column, it is then only necessary to update it in the model remove() method.
+* Since there is no need for a relationship table since the model is one-to-one, the degree of freedom in design model class is greater.
+ → Business logic can be added to the model in a natural way.
+
+The disadvantage is that the amount of code increases a bit.
+
+##### In brief: Hide unnecessary information to the controller and the view.
+
+## API of Model
+
+In general, when classes are more independent they are also more reusable. It would therefore be desirable to let dependency of the model to be as small as possible.
+
+In Web applications, the DB is often used for store data in a persisting state, so that "model class" relates to "table". Web applications that must handle many kinds of data have to create many tables (models) accordingly. Because it is common when designing a DB schema to conduct data normalization, models will have a relationship with each other through their properties (fields).
+
+When coding the class of models, the following conventions are in place. These should be learnt.
+
+Use the texport() method to pass arguments to the view.
+This is equal to set to a variable from type QVariant (by using the setValue() method) in the following classes:
+
+ - public default constructor
+ - public copy constructor
+ - public destructor
+ - Declaration in Q_DECLARE_METATYPE macro (At the end of the header per file)
+
+Please read the [Qt documentation](http://doc.qt.io/qt-5/qmetatype.html){:target="_blank"} if you want to learn more about it.
+
+##### ★ A model that is created by the generator command already meets the minimum requirements to work.
+
+The model class that is created in the generator is inherited from the TAbstractModel class. I have inherited it in order to take advantage of its features. Additionally, convenient methods for handling ORM objects will be available, too. Basically, the inheritance is merely for reusability. Those models that don't access the database at all, don't need to deal with inheritance though.
+
+##### In brief: if you want to use an ORM object, you should inherit from the TAbstractModel class regardlessly.
+
+When the model is created by the generator, the getter/setter of each property and the class methods, that are equivalent to "create" and "read", are defined. The following example is an excerpt of the Blog class which we made in the [tutorial chapter]({{ site.baseurl }}/en/user-guide/tutorial/index.html){:target="_blank"}.
+
+```c++
+static Blog create(const QString &title, const QString &body);
+static Blog create(const QVariantMap &values);
+static Blog get(int id); // Get the model object with a specified ID
+static Blog get(int id, int lockRevision);
+static QList getAll(); // Get all model objects
+```
+
+When you run the create() method, the content of the object is stored in the database during its creation.
+
+Let's also look at the methods defined in TAbstractModel class:
+
+```c++
+virtual bool create(); // New
+virtual bool save(); // Save (New or Updated)
+virtual bool update(); // Update
+virtual bool remove(); // Remove
+virtual bool isNull() const; // Whether present in the DB
+virtual bool isNew() const; // Whether before saving to DB
+virtual bool isSaved() const; // Whether stored in the DB
+void setProperties(const QVariantMap &properties);
+```
+
+The save() method internally calls the create() method if the ORM object doesn't already exist, or the update() method if it does exist. So, if you don't want to distinguish between the create() and update() method, then you can simply use the save() method to call the model.
+
+The code which is generated here is only the tip of the iceberg. You can add or modify the property by shifting, for example, from *protected* to *private* or whatever you like.
+
+## Creating a Model with a Different Name to the Table Name
+
+When you create a model using the generator command, the model name are derived from the table name in this format '_' (underscore).
+If you want to give an individual model a different name with this format, you can deal with it using the command with a string at the end such as follows:
+
+```
+ $ tspawn model blog_entries BlogEntry ← only model created
+ $ tspawn s blog_entries BlogEntry ← model-view-controller created
+```
+
+## Creating an Original Model
+
+You don't necessarily have to associate a model with the table. It can also be used to summarize relevant data in the case of passing information to the view.
+
+If you want to create a model on its own without the use of a generator, you should declare a class as shown in the following example:
+
+```c++
+class T_MODEL_EXPORT Post
+{
+ public:
+ // include default constructor, copy constructor, destructor
+ // write the code freely afterward.
+};
+Q_DECLARE_METATYPE(Post) // charm to pass to view
+Q_DECLARE_METATYPE(QList) // charm to pass the list to view
+```
+
+Save it in the models directory, add files to the project (*models.pro*), and specify the file name of the source and header.
diff --git a/docs/de/user-guide/model/object-document-mapping-on-mongodb.md b/docs/de/user-guide/model/object-document-mapping-on-mongodb.md
new file mode 100644
index 000000000..57f055f20
--- /dev/null
+++ b/docs/de/user-guide/model/object-document-mapping-on-mongodb.md
@@ -0,0 +1,156 @@
+---
+title: Object-Document Mapping in MongoDB
+page_id: "060.060"
+---
+
+## Object-Document Mapping in MongoDB
+
+MongoDB expresses data to be saved in a JSON-like format and saves it as a document. The function of associating such a document with an object in a programming language is called **object-document mapping (O/D mapping)**.
+
+As in the [O/R mapping](/en/user-guide/model/or-mapping.html){:target="_blank"} chapter described, one document here is also associated with one object in the O/D mapping.
+
+Since MongoDB documents are JSON-like formats, it is possible to have a hierarchical (nested) structure, but in O/D mapping, an object doesn't correspond to two or more levels of documents. For example, the following example shows the only supported simple form in O/D mapping:
+
+```json
+{
+ "name": "John Smith",
+ "age": 20,
+ "email": "foo@example.com"
+}
+```
+
+## Setup
+
+If you are not sure anymore how to setup a MongoDB connection properly, please refer to the [Access MongoDB](/en/user-guide/model/access-mongodb.html){:target="_blank"} chapter.
+
+For generating the class for O/D mapping, execute the following command in the application root directory. In this example, we create a collection named *foo*. The name of the model will be *Foo*.
+
+```
+ $ tspawn mm foo
+ created models/mongoobjects/fooobject.h
+ created models/foo.h
+ created models/foo.cpp
+ updated models/models.pro
+```
+
+The next step is to define the data to be stored in the document. Then we edit the c++ header file *models/mongoobjects/fooobject.h* by adding the QString variables *title* and *body*.
+
+```c++
+class T_MODEL_EXPORT FooObject : public TMongoObject, public QSharedData
+{
+public:
+ QString title; // ← Add here
+ QString body; // ← Add here
+ QString _id;
+ QDateTime createdAt;
+ QDateTime updatedAt;
+ int lockRevision;
+ enum PropertyIndex {
+ Id = 0,
+ CreatedAt,
+ UpdatedAt,
+ LockRevision,
+ };
+ :
+```
+
+Variables other than **_id** are not mandatory, so you can delete them. The variable *_id* is equivalent to the ObjectID in MongoDB, therefore please **don't** delete it.
+
+- This object is responsible for accessing MongoDB, which is why we call it "Mongo object" from the time being.
+
+Execute the following command again in order to reflect the added contents to other files.
+
+```
+ $ tspawn mm foo
+```
+
+Type 'Y' for all files with changes.
+This completes the model with [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete){:target="_blank"}.
+
+If you want to generate scaffolds including *controllers* and *views*, you can execute the following command instead of 'tspawn mm foo'.
+
+```
+ $ tspawn ms foo
+```
+
+Now, scaffolding has been generated. After compiling, try running the AP server.
+
+```
+ $ treefrog -d -e dev
+```
+
+By accessing *http://localhost:8800/foo/* in the browser, a screen which contains a list will be displayed. Use this screen as a starting point for registering, editing and deleting data.
+
+As you can see, this file is similar to the migration file (in Rails), because you automatically define/change the layout of the Mongo document by editing the class of the Mongo object.
+
+## Read a Mongo object
+
+Let's see how a Mongo object, which is referring to the class created by scaffolding, can be read. We do this by loading a Mongo object by using the object ID as a key.
+
+```c++
+QString id;
+id = ...
+TMongoODMapper mapper;
+FooObject foo = mapper.findByObjectId(id));
+```
+
+## Create a Mongo object
+
+Make it the same way as instantiating ordinary objects by setting properties. After this is done, calling the *create()* method will create a new document in the MongoDB for you.
+
+```c++
+FooObject foo;
+foo.title = ...
+foo.body = ...
+foo.create();
+```
+
+Since the object ID is generated automatically, please don't set anything.
+
+## Update a Mongo object
+
+Obtain the Mongo object, for example, by calling its object ID and set a new value. When this is done, the *update()* method will eventually update the object in the MongoDB internally.
+
+```c++
+TMongoODMapper mapper;
+FooObject foo = mapper.findByObjectId(id));
+foo.title = ...
+foo.update();
+```
+
+There is also a *save()* method for saving the document.
+This calls *create()* method **if the corresponding document does not exist** in the MongoDB, and then the *update()* method **if it exists**.
+
+## Delete a Mongo object
+
+Deleting a Mongo object deletes the document. Use the *remove()* method to remove the object.
+
+```c++
+TMongoODMapper mapper;
+FooObject foo = mapper.findByObjectId(id));
+foo.remove();
+```
+
+##### Supplement
+
+As mentioned above, Mongo objects can be used in the same way as ORM objects (O/R mapper objects). Looking from the controller's point of view, since the functions provided by the model class are the same, there is no difference in their use. These objects are hidden in the 'private' area of the model.
+
+In other words, if you define model class names which do not overlap, you can even have access to MongoDB and RDB simultaneously, which enables you to easily distribute data to multiple DB systems. If implemented correctly, you can reduce the load of RDB that sometimes may tend to be a bottleneck of the system.
+However, when distributing it, you should consider whether the data is supposed to be saved in RDB or in MongoDB depending on the nature of the data. Probably, the question is whether you really want to use transactions or not?
+
+In this way, you can easily access to database systems with different mechanisms which gives you the opportunity to build highly scalable systems as a Web application.
+
+**Differences between the Mongo object class and the ORM object class:**
+
+In a Mongo object class, you can define **QStringList**s as an instance variable like the following sequence of code visualizes:
+
+```c++
+class T_MODEL_EXPORT FooObject : public TMongoObject, public QSharedData
+{
+public:
+ QString _id;
+ QStringList texts;
+ :
+```
+
+* Please consider: **QStringList** cannot be defined in ORM object classes.
\ No newline at end of file
diff --git a/docs/de/user-guide/model/or-mapping.md b/docs/de/user-guide/model/or-mapping.md
new file mode 100644
index 000000000..989ed22f2
--- /dev/null
+++ b/docs/de/user-guide/model/or-mapping.md
@@ -0,0 +1,240 @@
+---
+title: O/R Mapping
+page_id: "060.010"
+---
+
+## O/R Mapping
+
+The model accesses the database internally through O/R mapping objects. This object will basically be a one-to-one relationship and will be referred to as an ORM object. It can be represented by a diagram such as the following:
+
+
+
+One record is related to one object. However, there are often cases of one-to-many relationships.
+Because the model is a collection of information to be returned to the browser, you need to understand how to access and manipulate the RDB ORM object.
+
+The following DBMS (driver) are supported (this is equivalent to Qt supports):
+
+* MySQL
+* PostgreSQL
+* SQLite
+* ODBC
+* Oracle
+* DB2
+* InterBase
+
+As we proceed with the description, let's check the correspondence of terms between RDB and object-oriented language.
+
+
+
+**Term correspondence table**
+
+
+
+
+
+| Object-orientation | RDB |
+|--------------------|--------|
+| Class | Table |
+| Object | Record |
+| Property | Field |
+
+
+
+## Database Connection Information
+
+The connection information for the database is specified in the configuration file (*config/database.ini*). The content of the configuration file is divided into three sections: *product*, *test*, and *dev*. By specifying options (-e) in the Web application startup command string (treefrog), you can switch the database. In addition, you can do so by adding a section.
+
+Parameters that can be set are the following:
+
+
+
+| Parameters | Description |
+|----------------|--------------------------------------------------------------------------------|
+| driverType | Driver typeChoose from: QMYSQL, QPSQL, QSQLITE, QODBC, QOCI, QDB2, QIBASE |
+| databaseName | Database name Specify the file path in the case of SQLite, e.g. *db/dbfile* |
+| hostName | Host name |
+| port | Port |
+| userName | User name |
+| password | Password |
+| connectOptions | Connect options Refer to Qt documentation [QSqlDatabase::setConnectOptions()](http://doc.qt.io/qt-5/qsqldatabase.html){:target="_blank"} |
+
+
+
+In this way, when you start a Web application, the system will manage the database connection automatically. From developer side, you don't need to deal with the process of opening or closing the database.
+
+After you create a table in the database, set the connection information in the dev section of the configuration file.
+
+The following sections will be using the *BlogObject* class as an example which I made in the [tutorial chapter]({{ site.baseurl }}/en/user-guide/tutorial/index.html){:target="_blank"}.
+
+## Reading ORM Object
+
+This is the most basic operation. It deals with finding documents in a given table. The passed *id* in the findByPrimaryKey() method here is supposed to find a document inside the table which matches with one of the ids (set as primary key). If a match has been decected, the content of the record will be then read.
+
+```c++
+int id;
+id = ...
+TSqlORMapper mapper;
+BlogObject blog = mapper.findByPrimaryKey(id);
+```
+
+You can also read all records by using the findAll() method.
+
+```c++
+TSqlORMapper mapper;
+QList list = mapper.findAll();
+```
+
+You must be careful with this; there is a possibility when the number of record is large, using read all would consume the memory. You can set an upper boundary using the setLimit() method.
+
+The SQL statement is generated inside the ORM. To see what query was issued, please check the [query log]({{ site.baseurl }}/en/user-guide/helper-reference/logging/html){:target="_blank"}.
+
+## Iterator
+
+If you want to deal with the search results one by one, you can use the iterator.
+
+```c++
+TSqlORMapper mapper;
+mapper.find(); // execute queries
+TSqlORMapperIterator i(mapper);
+while (i.hasNext()) { // Itaration
+ BlogObject obj = i.next();
+ // do something ..
+}
+```
+
+## Reading ORM Object by Specifying the Search Criteria
+
+Search criterias are specified in the TCriteria class. Importing just a single record such as "Hello world" into the *Title* folder can be done in the following manner:
+
+```c++
+TCriteria crt(BlogObject::Title, "Hello world");
+BlogObject blog = mapper.findFirst(crt);
+if ( !blog.isNull() ) {
+ // If the record exists
+} else {
+ // If the record does not exist
+}
+```
+
+You can also combine and apply multiple conditions.
+
+```c++
+// WHERE title = "Hello World" AND create_at > "2011-01-25T13:30:00"
+TCriteria crt(BlogObject::Title, tr("Hello World"));
+QDateTime dt = QDateTime::fromString("2011-01-25T13:30:00", Qt::ISODate);
+crt.add(BlogObject::CreatedAt, TSql::GreaterThan, dt); // AND add to the end operator
+
+TSqlORMapper mapper;
+BlogObject blog = mapper.findFirst(crt);
+ :
+```
+
+If you want to create conditions connect by the OR operator, use the addOr() method.
+
+```c++
+// WHERE title = "Hello World" OR create_at > "2011-01-25T13:30:00" )
+TCriteria crt(BlogObject::Title, tr("Hello World"));
+QDateTime dt = QDateTime::fromString("2011-01-25T13:30:00", Qt::ISODate);
+crt.addOr(BlogObject::CreatedAt, TSql::GreaterThan, dt); // OR add to the end operator
+ :
+```
+
+If you add a condition in the addOr() method, the condition clause is enclosed in parentheses. If you use a combination of add() and addOr() methods, take care about the order in which they are called.
+
+##### NOTE
+
+Remember, that when using AND and OR operators together, the AND operator has priority during its evaluation. That means, when expressions mix AND and OR operators, the AND operator is evaluated from the expression first, while the OR operator is evaluated in the second place. If you don't wish an operator to be evaluated in this order, you have to parantheses.
+
+## Create an ORM Object
+
+Create an ORM object in the same way as an ordinary object and then set its properties. Use the create() method to insert it in the database.
+
+```c++
+BlogObject blog;
+blog.id = ...
+blog.title = ...
+blog.body = ...
+blog.create(); // Inserts to DB
+```
+
+## Update an ORM Object
+
+In order to update an ORM object, you need to create an ORM object first, before its record can be read. Once you have fetched an ORM object from the database, you can set the properties and save its new state with the update() method.
+
+```c++
+TSqlORMapper mapper;
+BlogObject blog = mapper.findByPrimaryKey(id);
+blog.title = ...
+blog.update();
+```
+
+## Delete an ORM Object
+
+Removing ORM object means removing its record as well.
+Reads the ORM object and then deletes it by the remove() method.
+
+```c++
+TSqlORMapper mapper;
+BlogObject blog = mapper.findByPrimaryKey(id);
+blog.remove();
+```
+
+Like other methods, you can remove the records that match the criteria directly, without creating an ORM object.
+
+```c++
+// Deletes records that the Title field is "Hello"
+TSqlORMapper mapper;
+mapper.removeAll( TCriteria(BlogObject::Title, tr("Hello")) );
+```
+
+## Automatic ID Serial Numbering
+
+In some database systems, there is an automatic numbering function for fields. For example, in MySQL, the AUTO_INCREMENT attribute, with the equivalent in PostgreSQL being a field of serial type.
+
+The TreeFrog Framework is also equipped with this mechanism. That means, in the examples below numbers are assigned automatically. There is no need to update or to register a new value model.
+First, create a table with a field for the automatically sequenced number. Then, when the model is created by the generator command, we don't to manually apply updating the field (here 'id') anymore.
+
+Example in MySQL:
+
+```sql
+ CREATE TABLE animal ( id INT PRIMARY KEY AUTO_INCREMENT, ...
+```
+
+Example in PostgreSQL:
+
+```sql
+ CREATE TABLE animal ( id SERIAL PRIMARY KEY, ...
+```
+
+## Automatically Saving og the Date and Time while Creation and Update
+
+There are often cases where you want to store information such as date and time or the date and time when a record has been once created. Since this is a routine implementation, the field names can be set up in accordance with the rules in advance, so that the framework takes care of it by itself automatically.
+
+For saving date and time in case of a record creation, you can use the field name called *created_at*. Use the field name *updated_at* instead for saving date and time when updating a record. We use the TIMESTAMP type here for our purpose. If there is such a field, the ORM object sets a time stamp.
+
+
+
+| Item | Field Name |
+|------------------------------------------|---------------------------|
+| Saving the date and time of creation | created_at |
+| Saving the date and time of modification | updated_at OR modified_at |
+
+
+
+The tools for storing date and time automatically are handeled by the database itself as well. My recommendation is that, even though it can be done quite well in the database, it's better to do it in the framework.
+
+It doesn't really matter either way, I think either that we do not care, but by using the framework, you can define elaborate field names as you wish and leave the database side to do the rest.
+
+## Optimistic Locking
+
+The optimistic locking is a way to save data while verifying that it is not updated by others, without doing "record locking" while updating is taking place. The update is abandoned if another update is already taking place.
+
+In advance, prepare a field named *lock_revision* as an integer to record also using the auto increment ability. Lock revision is then incremented with each update. When reading the value and it is found to be different from that in the update, it means that it has been updated from elsewhere. Only if the values are the same, the update proceeds. In this way, we are able to securely proceeds updates. Since lock is not used, saving of DB system memory and an improvement in processing speeds, even if these are slight, can be expected.
+
+To take advantage of optimistic locking in the SqlObject, add an integer type field named *lock_revision* to the table. It creates a class using the generator. With this alone, optimistic locking is activated when you call TSqlObject::remove() method and TSqlObject::update() method.
+
+##### In brief: Create a field named lock_revision from type integer in the table.
diff --git a/docs/de/user-guide/model/partitioning.md b/docs/de/user-guide/model/partitioning.md
new file mode 100644
index 000000000..e6a492754
--- /dev/null
+++ b/docs/de/user-guide/model/partitioning.md
@@ -0,0 +1,75 @@
+---
+title: Partitioning
+page_id: "060.040"
+---
+
+## Partitioning
+
+Partitioning is used to put table A and table B on different servers to balance the load on the DB. On a Web system, the database is often the bottleneck of the whole system.
+
+As the amount of data in the table rests in the memory of the DB server (equivalent to disk I/O), it creates an increasing a loss of performance. The simplest answer may be to expand the memory (because memory is cheap these days). However, there are various problems with this solution, therefore it may be not as simple as expected first.
+
+It may be possible to increase the DB server itself, and it is worth considering partitioning of the server load. However, this is a difficult issue, server scaling depends on the size of the DB. Many helpful books have been published on this subject. For this reason, I will not discuss this here any further.
+
+The TreeFrog Framework provides a mechanism for partitioning, giving easy access data on a different DB server.
+
+## Partitioning by SqlObject
+
+As a prerequisite, we use table A for host A, and table B for host B.
+
+First, make separate database configuration files describing the hosts connection information. The file names must be *databaseA.ini* and *databaseB.ini* respectively. They should be located in the config directory. For the contents of the file, write the appropriate values. Here is an example of the way the *dev* section might be defined.
+
+```ini
+[dev]
+DriverType=QMYSQL
+DatabaseName=foodb
+HostName=192.168.xxx.xxx
+Port=3306
+UserName=root
+Password=xxxx
+ConnectOptions=
+```
+
+Next define the file names of the database configuration files in the application configuration file (*application.ini*). Use *DatabaseSettingsFiles* with the values written side by side and seperate them by spaces.
+
+```ini
+# Specify setting files for databases.
+DatabaseSettingsFiles=databaseA.ini databaseB.ini
+```
+
+The database IDs follow the sequence 0, 1, 2, … as per following the example:
+
+* The database ID of the host A : 0
+* The database ID of the host B : 1
+
+Then, set the header file of SqlObject with this database ID.
+Edit the header file that is created by the generator. You can also override the databaseId() method by the returned database ID.
+
+```c++
+class T_MODEL_EXPORT BlogObject : public TSqlObject, public QSharedData
+{
+ :
+ int databaseId() const { return 1; } // returns ID 1
+ :
+};
+```
+
+By doing this, queries for BlogObject will be issued to host B. After that, we can just use the SqlObject as in the past.
+
+The example here was made with two DB servers, but is also compatible with three or more DB servers. Simply add the *DatabaseSettingsFiles* in the configuration file.
+
+Thus, partitioning can be applied without changing the logic of the model and controller.
+
+## Querying Partitioned Tables
+
+As discussed in the [SQL query]({{ site.baseurl }}/en/user-guide/model/sql-query.html){:target="_blank"}, the TSqlQuery is not only used to issue a query on its own, or it doesn't need to extract all values, but you can use it to apply to the partitioning.
+
+As follows, the database ID is specified in the second argument to the constructor:
+
+```c++
+TSqlQuery query("SELECT * FROM foo WHERE ...", 1); // specifies database ID 1
+query.exec();
+ :
+```
+
+This query is then therefore executed to host B.
\ No newline at end of file
diff --git a/docs/de/user-guide/model/sql-query.md b/docs/de/user-guide/model/sql-query.md
new file mode 100644
index 000000000..5895fbdc8
--- /dev/null
+++ b/docs/de/user-guide/model/sql-query.md
@@ -0,0 +1,96 @@
+---
+title: SQL Query
+page_id: "060.020"
+---
+
+## SQL Query
+
+SqlObject function is sufficient when you need to read a simple record, but when the processing is complex such as when relating to multiple tables, you may want to publish an SQL query directly. In this framework, it is possible to generate a query safely by using a placeholder.
+
+The following code is an example of issuing a query using placeholders for ODBC format:
+
+```c++
+TSqlQuery query;
+query.prepare("INSERT INTO blog (id, title, body) VALUES (?, ?, ?)");
+query.addBind(100).addBind(tr("Hello")).addBind(tr("Hello world"));
+query.exec(); // Query execution
+```
+
+Here is an example using a named placeholder:
+
+```c++
+TSqlQuery query;
+query.prepare("INSERT INTO blog (id, title, body) VALUES (:id, :title, :body)");
+query.bind(":id", 100).bind(":title", tr("Hello")).bind(":body", tr("Hello world"));
+query.exec(); // Query execution
+```
+
+How to retrieve the data from the query result is the same as the QSqlQuery class of Qt:
+
+```c++
+TSqlQuery query;
+query.exec("SELECT id, title FROM blog"); // Query execution
+while (query.next()) {
+ int id = query.value(0).toInt(); // Convert the field first to int type
+ QString str = query.value(1).toString(); // Convert the second field to QString type
+ // do something
+}
+```
+
+The same method can be used for the TSqlQuery class, because it inherits the [QSqlQuery class](https://doc.qt.io/qt-5/qsqlquery.html){:target="_blank"} of Qt.
+
+##### In brief: queries can be created using placeholders in all cases.
+
+In fact, you can see any query that has been executed in the [query log]({{ site.baseurl }}/en/user-guide/helper-reference/logging.html){:target="_blank"} file.
+
+## Reading a Query From a File
+
+Because it's necessary to compile after every time you write or modify a query statement in the source code, you might find it a bit of a hassle during the application development. To alleviate this, there is a mechanism for writing only query statements to a separate file to be loaded at runtime.
+
+The file is placed in the sql directory (however, the directory can be changed through the *application.ini*). The *insert_blog.sql* is temporary, I'll describe the contents below.
+
+```sql
+INSERT INTO blog (id, title, body) VALUES (?, ?, ?)
+```
+
+The following is the source code. We will read the *insert_blog.sql* file with the load() method.
+
+```c++
+TSqlQuery query;
+query.load("insert_blog.sql")
+query.addBind(100).addBind(tr("Hello")).addBind(tr("Hello world"));
+query.exec(); // Query execution
+```
+
+The cache works inside the load() method (but only when thread module is applied in [MPM]({{ site.baseurl }}/en/user-guide/performance/index.html){:target="_blank"}. The query is read from the file only on the first occasion, after that it is used from the cache memory, so it then works at high speed.
+After the file has been updated, we need to restart the server in order to read the query statement.
+
+```
+ $ treefrog -k abort ; treefrog -d -e dev
+```
+
+Or like the following:
+
+```c++
+ $ treefrog -k restart
+```
+
+## Get an ORM Object from the Result of a Query
+
+In the above method, it is necessary to retrieve the value of every field from the results of the query; however, single records can be extracted as ORM objects in the following manner.
+
+Run the query using the TSqlQueryMapper object. Then extract the ORM object from the results using an iterator. It's important to specify the 'blog. *' in the SELECT statement in order to select and target all fields.
+
+```c++
+TSqlQueryORMapper mapper;
+mapper.prepare("SELECT blog.* FROM blog WHERE ...");
+mapper.exec(); // Query execution
+TSqlQueryORMapperIterator it(mapper);
+while (it.hasNext()) {
+ BlogObject obj = it.next();
+ // do something
+ :
+}
+```
+
+If you need to extract only one ORM object and you can get the results using the execFirst() method.
\ No newline at end of file
diff --git a/docs/de/user-guide/model/transaction.md b/docs/de/user-guide/model/transaction.md
new file mode 100644
index 000000000..d32886905
--- /dev/null
+++ b/docs/de/user-guide/model/transaction.md
@@ -0,0 +1,39 @@
+---
+title: Transaction
+page_id: "060.030"
+---
+
+## Transaction
+
+If the DBMS supports transaction, the transaction will work by default; then, when you launch the app, it is already working.
+
+The framework starts the transaction just before the action is called, and after being called, it commits the transaction.
+
+If something abnormal occurs and you want to roll back the transaction, you can throw an exception or call rollbackTransaction() method in the controller. A Rollback should be implemented after completing the action.
+
+```c++
+// in an action
+ :
+if (...) {
+ rollbackTransaction();
+ :
+}
+```
+
+If you don't want to activate the transaction itself deliberately, you can override the transactionEnabled() method of the controller and then return *false*.
+
+```c++
+bool FooController::transactionEnabled() const
+{
+ return false;
+}
+```
+
+You can set each controller, as in this example, or, if you don't want to use it all, you can override in ApplicationController.
+
+```c++
+bool ApplicationController::transactionEnabled() const
+{
+ return false;
+}
+```
\ No newline at end of file
diff --git a/docs/de/user-guide/performance/index.md b/docs/de/user-guide/performance/index.md
new file mode 100644
index 000000000..707a52874
--- /dev/null
+++ b/docs/de/user-guide/performance/index.md
@@ -0,0 +1,88 @@
+---
+title: Performance
+page_id: "160.0"
+---
+
+## Performance
+
+### Creating the Application Server
+
+The TreeFrog Application server (AP server) is created by a server process that handles HTTP (*tadpole*) and a process that monitors its life and death (*treefrog*).
+
+If a segmentation fault causes the *tadpole* process to go down, the *treefrog* process will detect it and then restart the *tadpole* process. This kind of fault-tolerant mechanism makes it possible for the service itself to be provided continuously.
+
+## Multi-Processing Module – MPM
+
+There are two MPMs (Multi-Processing Modules) to create multiprocessing modules for the application server (AP server): *prefork* and *thread*. These are similar to Apache. You need to choose one of them and then specify it in setting file. The default is 'thread'.
+
+* **prefork:** Create the process "fork" in advance, and then create socket as "listen". The action is performed during the process, and when the request has been operated and the response returned, the process disappears. Do not reuse it! If the action is down by fault or illegal operation, it wouldn't then affect any actions. **[Deprecated]**
+* **thread:** Thread is created every time when there is a request. Action runs on the thread and when the request has been processed and the response sent, the thread disappears. The performance is good.
+* **hybrid:** Sockets are monitored by epoll system call and an HTTP request is processed on a thread. It's available on Linux only. It is implemented for the C10K problem that can maintain many sockets.
+
+If you use the thread module, performance can be very high (about 14x of 'prefork'). If you use the hybrid module on Linux, performance can be much better at high level load. However, when, for example, a segmentation fault occurs, each process can go down, therefore all threads can be down. If a certain action has a fault, other parallel running actions could also be affected. That would cause problems. In the case of the prefork module the process is divided into individual actions, so that this kind of concern can be avoided.
+
+In addition, in case of using the thread or hybrid module setting, when a web application has a memory leak fault, by continuing operation, sooner or later the memory will be used up. Of course, the memory leak bug should be fixed, but if you cannot solve it, you can use the prefork module. Each time a process is exited you can avoid the memory being eaten up. However, it is annoying!
+Be sure to consider the mentioned things above when choosing an MPM.
+
+## Benchmark
+
+The following comparisons use a sample application (blogapp) and the benchmark software *httperf*.
+
+**Test environment:**
+
+* PC: MacBook Pro [ 2.4GHz Intel Core 2 Duo, 4GB 1067MHz DDR3 ]
+* OS: Mac OS X 10.6
+* DB: SQLite (no record)
+* Qt: 4.7 (Qt SDK 2010.05)
+* TreeFrog: 0.54 (compiled by -O2 option)
+
+**Test Method**
+
+* The performance here is measured by sending huge amount of requests to */blog/index* in localhost in one connection. Httperf is used.
+
+The framework, individual requests, controller, model, DB, and view are all comprehensively checked. Since the DB cache system is not implemented (in the case of 0.54), an SQL query is called to the DB each time.
+
+In the case of the thread module:
+**Parameter: MPM.thread.MaxServers=20**
+
+```
+ $ httperf –server=localhost –port=8800 –uri=/Blog/index/ –num-conns=10000 –num-calls=1
+ httperf –client=0/1 –server=localhost –port=8800 –uri=/Blog/index/ –send-buffer=4096
+ –recv-buffer=16384 –num-conns=10000 –num-calls=1
+ httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE
+ Maximum connect burst length: 1
+ Total: connections 10000 requests 10000 replies 10000 test-duration 17.800 s
+
+ Connection rate: 561.8 conn/s (1.8 ms/conn, <=1 concurrent connections)
+ Connection time [ms]: min 0.3 avg 1.8 max 17.5 median 1.5 stddev 0.5
+ Connection time [ms]: connect 0.1
+ Connection length [replies/conn]: 1.000
+
+ Request rate: 561.8 req/s (1.8 ms/req)
+ Request size [B]: 73.0
+
+ Reply rate [replies/s]: min 555.4 avg 562.3 max 566.8 stddev 6.1 (3 samples)
+ Reply time [ms]: response 1.7 transfer 0.0
+ Reply size [B]: header 313.0 content 421.0 footer 0.0 (total 734.0)
+ Reply status: 1xx=0 2xx=10000 3xx=0 4xx=0 5xx=0
+
+ CPU time [s]: user 3.13 system 13.73 (user 17.6% system 77.1% total 94.7%)
+ Net I/O: 442.7 KB/s (3.6*10^6 bps)
+
+ Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
+ Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
+```
+
+* By running the test several times, I was able to find an intermediate result, as posted above ↑
+
+About 562 times requests are executed per second. This is the number when the record is 0, so that it would represents the highest performance figure of which TreeFrog is capable. I think it indicates top class performance in the web application framework. What do you think?
+
+In real web applications, the logic of controller and model is more complicated, and there should would be a large number of records, so performance would be less than the above. These figures should therefore be taken as a reference.
+
+##### In brief: Use 'thread' as your MPM. If using the WebSocket protocol, consider setting 'hybrid' as well.
+
+### Benchmarks Site
+
+This following site published benchmarks for web application frameworks.
+
+- [Web Framework Benchmarks](https://www.techempower.com/benchmarks)
diff --git a/docs/de/user-guide/security/index.md b/docs/de/user-guide/security/index.md
new file mode 100644
index 000000000..c92cebc26
--- /dev/null
+++ b/docs/de/user-guide/security/index.md
@@ -0,0 +1,59 @@
+---
+title: Security
+page_id: "100.0"
+---
+
+## Security
+
+Once you publish the website, you have to understand the threats it faces and set security measures. The application developer has to program carefully in order to avoid vulnerability on the web. You can find detailed articles on the internet, that's why I'll not go to deept into detail here.
+
+Since TreeFrog has an inbuilt security system, you can establish a safe website when using it properly.
+
+## SQL Injection Prevention
+
+As you will know, SQL injection means that due to the problems of SQL sentence construction, the database can be attacked or misused. TreeFrog advises observance of the following SQL injection measures:
+
+* Use ORM object => you can make safe SQL query sentences inside.
+* Use TSqlQuery place holder when constructing SQL sentences => the values are processed by escape automatically.
+* When constructing SQL sentences by string concatenation, use TSqlQuery::escapeIdentifier() for field name, and TSqlQuery::formatValue() for value. => escape processing is done for each.
+
+## Cross-site Scripting Prevention (CSRF)
+
+If there is a deficiency in the process of generating websites, it can allow the inclusion of malicious scripts, and if that happens, a cross-site scripting attack can be established. In order to guard against this, you should implement a policy of using escape for all values and attribute outputs which output dynamically into the view area. In the TreeFrog, the following is done:
+
+* The eh() method or '<%= .. %>' notation should be used for outputting values.
+
+You have to be very careful if you output the area WITHOUT using the escape processing, that is the echo() method or '<%= .. %>' notation.
+
+Basically, for the content of any \ element, I recommend you to not dynamically output any information dependent on outside input.
+
+## CSRF Protection
+
+Any site that accepts user requests without any verification, has a possible vulnerability to CSRF (Cross-Site Request Forgery) exists. If an HTTP request has been trumped by a third party, you have to discard it.
+
+To prevent this, perform the followings both.
+
+ * As for the information on the form, ONLY accept requests in the POST method.
+ * Put a row of letters that is difficult to predict as a hidden parameter on one of the information items within the form, and validate it when receiving it. => by generating a form tag with the formTag() method, the hidden parameter is automatically granted.
+
+If this hidden parameter is easily predictable, this CSRF protection is insufficient. This parameter is a string that has been converted by the hash function, using the Session.Secret parameter, in the *application.ini* configuration file. It is therefore sufficiently difficult for the string to be guessed by anyone not knowing the *Session.Secret* value.
+
+In order to turn on the CSRF protection, you need to set the following in the *application.ini* file:
+
+```
+ EnableCsrfProtectionModule=true
+```
+
+I would recommend that you turn this feature off during the development of the application.
+
+##### In brief: Generate a form tag using the formTag() method.
+
+## Session Hijacking Prevention
+
+When a session ID is easily guessed or stolen, spoof-like acts are possible. This kind of spoof-like conduct is called session hijacking.
+
+In the TreeFrog Framework, as a defense against session hijacking, a new session ID of sufficient length to avoid being guessed is generated using random number and a hash function each time the site is accessed. In that way the session ID is extremely difficult to guess and, for a general site, provides what is thought to be adequate protection.
+
+Although guessing a session ID is difficult, a more serious threat is possible eavesdropping on the network. To counter this, it is possible to encrypt (SSL) the communication channel by reverse proxy (such as nginx or Apache).
+
+##### In brief: Encrypt by SSL all sites where important information is being dealt with.
diff --git a/docs/de/user-guide/test/index.md b/docs/de/user-guide/test/index.md
new file mode 100644
index 000000000..5838d48ef
--- /dev/null
+++ b/docs/de/user-guide/test/index.md
@@ -0,0 +1,175 @@
+---
+title: Test
+page_id: "120.0"
+---
+
+## Test
+
+In the process of application development, testing is very important. Testing requires checking by repeating, and it is a boring process. For this reason, it might be very useful to automate this process.
+
+## Unit Test of the Model
+
+In this session, we will try to check if the model works the right way. The test framework follows TestLib attached by Qt (please check out the [documentation](http://qt-project.org/doc/qt-5.0/qttestlib/qtest-overview.html){:target="_blank"} for more details).
+
+Let's test the Blog model code that we made in the [tutorial](/en/user-guide/tutorial/index.html){:target="_blank"}. Make a common library for the model in advance. At first, we will create a working directory in the *test* directory.
+
+```
+ $ cd test
+ $ mkdir blog
+ $ cd blog
+```
+
+We will try to create the test case for creating and reading of the Blog model.
+For example, let's set the name of the implementing test as follows: *TestBlog*. The source code with the following content is saved as a file named *testblog.cpp*.
+
+```c++
+#include
+#include "models/blog.h" // include the model class
+
+class TestBlog : public QObject
+{
+ Q_OBJECT
+private slots:
+ void create_data();
+ void create();
+};
+
+void TestBlog::create_data()
+{
+ // definition of test data
+ QTest::addColumn("title");
+ QTest::addColumn("body");
+
+ // adding to test data
+ QTest::newRow("No1") << "Hello" << "Hello world.";
+}
+
+void TestBlog::create()
+{
+ // acquisition of test data
+ QFETCH(QString, title);
+ QFETCH(QString, body);
+
+ // logic of the test
+ Blog created = Blog::create(title, body);
+ int id = created.id();
+ Blog blog = Blog::get(id); // Getting model ID
+
+ // verification of result execution
+ QCOMPARE(blog.title(), title);
+ QCOMPARE(blog.body(), body);
+}
+
+TF_TEST_MAIN(TestBlog) // specify the class name you created
+#include "testblog.moc" // charm. Make the extension .moc
+```
+
+As supplemental comment, among this, create() method can do the test, and QCOMPARE macro can check the real returning value. The create_data() method works as passing test data to the create_data() method.
+The rule is always to put '_data' at the end of the method name.
+
+In this example, I am doing the following in create_data() method.
+
+* QTest::addColumn() function: Define the name and type of test data.
+* QTest::newRow() function: Add test data.
+
+The following is done in the create() method.
+
+* Fetch the test data.
+* Run the test logic.
+* Verify that the result is correct.
+
+Next, create a project file to make the *Makefile*. The file name is *testblog.pro*, saving the contents as the following.
+
+```
+ TARGET = testblog
+ TEMPLATE = app
+ CONFIG += console debug c++14
+ CONFIG -= app_bundle
+ QT += network sql testlib
+ QT -= gui
+ DEFINES += TF_DLL
+ INCLUDEPATH += ../..
+ LIBS += -L../../lib -lmodel
+ include(../../appbase.pri)
+ SOURCES = testblog.cpp # Specifying the file name
+```
+
+After you save the project file, you can create a binary by running the following command in its directory:
+
+```
+ $ qmake
+ $ make
+```
+
+Next, some little configuration needs to be done for the testing process.
+Because of the need to refer to the various configuration files, the test command requires a symbolic link to the config directory. Its location should be directly below of the test command. When SQLite is used for the database, we need to make a symbolic link to the *db* directory as well.
+
+```
+ $ ln -s ../../config config
+ $ ln -s ../../db db
+```
+
+If you use Windows, an exe file of the test is created in the *debug* directory, so that a symbolic link is created there. Please be careful: it is NOT a shortcut!
+To create a symbolic link, you must run the command from the command prompt launched with administrator privileges.
+
+```
+ > cd debug
+ > mklink /D config ..\..\..\config
+ > mklink /D db ..\..\..\db
+```
+
+Furthermore, take the path to the common library including the Blog model.
+In the case of Linux, set the environment variable as follows:
+
+```
+ $ export LD_LIBRARY_PATH=/path/to/blogapp/lib
+```
+
+If you use Windows, add the setting to PATH variables like this:
+
+```
+ > set PATH=C:\path\to\blogapp\lib;%PATH%
+```
+
+Then check the connection information for the database. In the unit test, the connection information in the test section in the database configuration file (*database.ini*) is used.
+
+```
+[test]
+DriverType=QMYSQL
+DatabaseName=blogdb
+HostName=
+Port=
+UserName=root
+Password=
+ConnectOptions=
+```
+
+The configuration is now complete. Next, the test needs to be executed. If the test was a throughout success, you can see the following message on the screen:
+
+```
+$ ./testblog
+Config: Using QtTest library 5.5.1, Qt 5.5.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.4.0 20160609)
+PASS : TestBlog::initTestCase()
+PASS : TestBlog::create(No1)
+PASS : TestBlog::cleanupTestCase()
+Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
+********* Finished testing of TestBlog *********
+```
+
+In the case of Windows, please execute the test on the TreeFrog Command Prompt.
+If, however, the result is not what was expected, you will see the following message.
+
+```
+********* Start testing of TestBlog *********
+Config: Using QtTest library 5.5.1, Qt 5.5.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.4.0 20160609)
+PASS : TestBlog::initTestCase()
+FAIL! : TestBlog::create(No1) Compared values are not the same
+ Actual (blog.body()): "foo."
+ Expected (body): "Hello world."
+ Loc: [testblog.cpp(35)]
+PASS : TestBlog::cleanupTestCase()
+Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted
+********* Finished testing of TestBlog *******
+```
+
+Make a test case for each each model. Then please do the test. The key to a good Web application development is to be sure that the model is working properly.
diff --git a/docs/de/user-guide/tutorial/index.md b/docs/de/user-guide/tutorial/index.md
new file mode 100644
index 000000000..d8b4160ec
--- /dev/null
+++ b/docs/de/user-guide/tutorial/index.md
@@ -0,0 +1,797 @@
+---
+title: Tutorial
+page_id: "030.0"
+---
+
+## Tutorial
+
+Let's create a TreeFrog Application.
+We'll try to make a simple blog system which can list, view, and add/edit/delete text.
+
+### Generate the Application Skeleton
+
+First we will need to make a skeleton (various settings files and a directory tree). We'll use the name "blogapp". Run the following command from the command line. (In Windows, please run from the TreeFrog Command Prompt).
+
+```
+ $ tspawn new blogapp
+ created blogapp
+ created blogapp/controllers
+ created blogapp/models
+ created blogapp/models/sqlobjects
+ created blogapp/views
+ created blogapp/views/layouts
+ created blogapp/views/mailer
+ created blogapp/views/partial
+ :
+```
+
+### Create a Table
+
+Now we need to create a table in the database. We'll create the field title and content (body). Here are examples in MySQL and SQLite'
+
+Example in MySQL:
+Set the character set to UTF-8. You can also specify this when generating the database (do ensure that it is being set correctly, see FAQ). You can specify the configuration file for the database, as described below. Also, make the path through into MySQL using the command line tool.
+
+```
+ $ mysql -u root -p
+ Enter password:
+
+ mysql> CREATE DATABASE blogdb DEFAULT CHARACTER SET utf8mb4;
+ Query OK, 1 row affected (0.01 sec)
+
+ mysql> USE blogdb;
+ Database changed
+
+ mysql> CREATE TABLE blog (id INTEGER AUTO_INCREMENT PRIMARY KEY, title VARCHAR(20), body VARCHAR(200), created_at DATETIME, updated_at DATETIME, lock_revision INTEGER) DEFAULT CHARSET=utf8;
+
+ Query OK, 0 rows affected (0.02 sec)
+
+ mysql> DESC blog;
+ +---------------+--------------+------+-----+---------+----------------+
+ | Field | Type | Null | Key | Default | Extra |
+ +---------------+--------------+------+-----+---------+----------------+
+ | id | int(11) | NO | PRI | NULL | auto_increment |
+ | title | varchar(20) | YES | | NULL | |
+ | body | varchar(200) | YES | | NULL | |
+ | created_at | datetime | YES | | NULL | |
+ | updated_at | datetime | YES | | NULL | |
+ | lock_revision | int(11) | YES | | NULL | |
+ +---------------+--------------+------+-----+---------+----------------+
+ 6 rows in set (0.01 sec)
+
+ mysql> quit
+ Bye
+```
+
+**Example in SQLite:**
+We are going to put the database files in the DB directory.
+
+```
+ $ cd blogapp
+ $ sqlite3 db/blogdb
+ SQLite version 3.6.12
+ sqlite> CREATE TABLE blog (id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(20), body VARCHAR(200), created_at TIMESTAMP, updated_at TIMESTAMP, lock_revision INTEGER);
+ sqlite> .quit
+```
+
+A blog table is created with the fields: id, title, body, created_at, updated_at, and lock_revision.
+
+With the fields updated_at and created_at, TreeFrog will automatically insert the date and time of creation and of each update. The lock_revision field, which is intended for use with optimistic locking, needs to be created as an integer type.
+
+#### Optimistic Locking
+
+The optimistic locking is used to store data while verifying that information is not locked by being updated by another user. Since there is no actual write lock, you can expect processing to be a little faster.
+See the section on O/R mapping for more information.
+
+## Set the Database Information
+
+Use _config/database.ini_ to set information about the database.
+Open the file in the editor, enter the appropriate values for your environment to each item in the [dev] section, and then click Save.
+
+Example in MySQL:
+
+```
+ [dev]
+ DriverType=QMYSQL
+ DatabaseName=blogdb
+ HostName=
+ Port=
+ UserName=root
+ Password=pass
+ ConnectOptions=
+```
+
+Example in SQLite:
+
+```
+ [dev]
+ DriverType=QSQLITE
+ DatabaseName=db/blogdb
+ HostName=
+ Port=
+ UserName=
+ Password=
+ ConnectOptions=
+```
+
+Once you have correctly set these details, it's time to display the table to access the DB.
+If everything is setup properly, it will display a message like this:
+
+```
+ $ cd blogapp
+ $ tspawn --show-tables
+ DriverType: QSQLITE
+ DatabaseName: db\blogdb
+ HostName:
+ Database opened successfully
+ -----
+ Available tables:
+ blog
+```
+
+If a required SQL driver is not included in the Qt SDK, the following error message will appear:
+
+```
+ QSqlDatabase: QMYSQL driver not loaded
+```
+
+If you receive this message, the Qt SQL driver may not be installed. Install the driver for the RDBM.
+
+You can check which SQL drivers are installed with the following command;
+
+```
+ $ tspawn --show-drivers
+ Available database drivers for Qt:
+ QSQLITE
+ QMYSQL3
+ QMYSQL
+ QODBC3
+ QODBC
+```
+
+The pre-built SQL driver can be used for SQLite, although the SQLite driver can also be used with a little effort.
+
+## Specifying a Template System
+
+In TreeFrog Framework, we can specify either Otama or ERB as a template system. We will set the TemplateSystem parameter in the _development.ini_ file.
+
+```
+TemplateSystem=ERB
+ or
+TemplateSystem=Otama
+```
+
+ERB is specified by default.
+
+## Automatic Generation of Code Created from the Table
+
+From the command line, run the command generator (tspawn) which will generate the underlying code. The example below shows the production of controller, model, and view. The table name is specified as the command argument.
+
+```
+ $ tspawn scaffold blog
+ DriverType: QSQLITE
+ DatabaseName: db/blogdb
+ HostName:
+ Database open successfully
+ created controllers/blogcontroller.h
+ created controllers/blogcontroller.cpp
+ updated controllers/controllers.pro
+ created models/sqlobjects/blogobject.h
+ created models/blog.h
+ created models/blog.cpp
+ updated models/models.pro
+ created views/blog
+ :
+```
+
+Depending on the tspawn option, only controllers or models can be generated.
+
+### Vue.js support
+
+In version 2 and later, it is possible to choose to generate views using [vue.js](https://vuejs.org/).
+
+```
+ :
+ Create sources for vue.js? [y/n] y ← Enter 'y'
+```
+
+### Reference: Help for tspawn command
+
+```
+ $ tspawn --help
+ usage: tspawn [args]
+
+ Type 'tspawn --show-drivers' to show all the available database drivers for Qt.
+ Type 'tspawn --show-driver-path' to show the path of database drivers for Qt.
+ Type 'tspawn --show-tables' to show all tables to user in the setting of 'dev'.
+ Type 'tspawn --show-collections' to show all collections in the MongoDB.
+
+ Available subcommands:
+ new (n)
+ scaffold (s) [model-name]
+ controller (c) action [action ...]
+ model (m) [model-name]
+ helper (h)
+ usermodel (u) [username password [model-name]]
+ sqlobject (o) [model-name]
+ mongoscaffold (ms)
+ mongomodel (mm)
+ websocket (w)
+ api (a)
+ validator (v)
+ mailer (l) action [action ...]
+ delete (d)
+```
+
+## Build the Source Code
+
+To start the build process, run the following command only once; it will generate a Makefile.
+
+```
+ $ qmake -r "CONFIG+=debug"
+```
+
+A WARNING message will be displayed, but there is actually no problem. Next, run the make command to compile the controller, model, view, and helper.
+
+```
+ $ make (On MSVC run 'nmake' command instead)
+```
+
+If the build succeeds, four shared libraries (controller, model, view, helper) will be created in the lib directory. By default, the library is generated in debug mode; however, you can regenerate the Makefile, using the following command, to create a library in release mode.
+
+Creating a Makefile in release mode:
+
+```
+ $ qmake -r "CONFIG+=release"
+```
+
+## To Start the Application Server
+
+Change to the root directory of the application before starting the application server (AP server). The server will start to process what it regards as the application root directory to the directory where the command is run. To stop the server, press Ctrl+c.
+
+```
+ $ treefrog -e dev
+```
+
+In Windows, start by using _treefrog**d**.exe_.
+
+```
+> treefrogd.exe -e dev
+```
+
+In Windows, start by using treefroge**d**.exe when you build web applications in debug mode, and start by using treefrog.exe when you want to build a web application in release mode.
+
+##### Release and debug modes should not be mixed, as the result will not work properly.
+
+If you want it to run in the background, use the option -d together with any other required options.
+
+```
+ $ treefrog -d -e dev
+```
+
+The command option '-e' appears in the above examples. When this is followed by a **section name** that you have specified in database.ini before, it can be used to change the database settings. If no section name is specified it is assumed that the command refers to a product (when the project is being made, the following three sections are predefined).
+
+
+
+| Section | Description |
+| ------- | ---------------------------------------- |
+| dev | For generator, development |
+| test | For test |
+| product | For official version, production version |
+
+
+
+'-e' comes from the initials letter of "environment".
+
+Stop command:
+
+```
+ $ treefrog -k stop
+```
+
+Abort command (forced termination):
+
+```
+ $ treefrog -k abort
+```
+
+Restart command:
+
+```
+ $ treefrog -k restart
+```
+
+If the firewall is in place, make sure that the correct port is open (the default is port 8800).
+
+The following command shows the current URL routing information.
+
+```
+ $ treefrog --show-routes
+ Available controllers:
+ match /blog/index -> blogcontroller.index()
+ match /blog/show/:param -> blogcontroller.show(id)
+ match /blog/create -> blogcontroller.create()
+ match /blog/save/:param -> blogcontroller.save(id)
+ match /blog/remove/:param -> blogcontroller.remove(id)
+```
+
+### Reference: Help for treefrog command
+
+```
+$ treefrog -h
+Usage: treefrog [-d] [-p port] [-e environment] [-r] [app-directory]
+Usage: treefrog -k [stop|abort|restart|status] [app-directory]
+Usage: treefrog -m [app-directory]
+Options:
+ -d : run as a daemon process
+ -p port : run server on specified port
+ -e environment : specify an environment of the database settings
+ -k : send signal to a manager process
+ -m : show the process ID of a running main program
+ -r : reload app automatically when updated (for development)
+
+Type 'treefrog --show-routes [app-directory]' to show routing information.
+Type 'treefrog --settings [app-directory]' to show application settings.
+Type 'treefrog -l' to show your running applications.
+Type 'treefrog -h' to show this information.
+Type 'treefrog -v' to show the program version.
+```
+
+## Browser Access
+
+We will now use your web browser to access http://localhost:8800/Blog. A list screen, such as the following should be displayed.
+
+Initially, there is nothing registered.
+
+
+
+
+
+
+
+When two items are registered the options show, edit, and remove become visible. As you can see, there is even no problem in displaying Japanese text.
+
+
+
+
+
+
+
+TreeFrog is equipped with a call method mechanism (Routing system) for the appropriate controller from the requested URL to the action (as well as other frameworks).
+Developed source code can work on other platforms, if it is re-built.
+
+To see a sample Web application. You can watch it [here](http://blogapp.treefrogframework.org/Blog){:target="\_blank"}.
+You can play with this and it will respond at the same speed as the average desktop application.
+
+## Source Code of Controller
+
+Let's take a look at the contents of the controller which is generated.
+First, the header file. There are several charm codes, but these are required for sending by URL.
+
+The purpose of public slots is to declare the actions (methods) you want to send. Actions corresponding to the [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete){:target="\_blank"} are defined. Incidentally, the slots keyword is a feature of the Qt extension. Please see the Qt documentation for more details.
+
+```c++
+class T_CONTROLLER_EXPORT BlogController : public ApplicationController {
+public slots:
+ void index(); // Lists all entries
+ void show(const QString &id); // Shows one entry
+ void create(); // New registration
+ void save(const QString &id); // Updates (save)
+ void remove(const QString &id); // Deletes one entry
+};
+```
+
+Next, explain the source file. The controller is responsible for invoking the view on request. Calls the service and depending on the result, it calls the template logic with the render() function or redirects with the redirect() function.
+It is important to **write the main processing in the service class and keep the controller logic simple**.
+
+```c++
+static BlogService service;
+
+void BlogController::index()
+{
+ service.index(); // Calls the service
+ render(); // Renders the view, index.erb
+}
+
+void BlogController::show(const QString &id)
+{
+ service.show(id.toInt()); // Calls the service
+ render(); // Renders the view, show.erb
+}
+
+void BlogController::create()
+{
+ int id;
+
+ switch (request().method()) { // Checks the incoming httpRequest method type
+ case Tf::Get: // GET Method
+ render();
+ break;
+ case Tf::Post: // POST Method
+ id = service.create(request()); // Calls the service
+ if (id > 0) {
+ redirect(urla("show", id)); // Redirects
+ } else {
+ render(); // Renders the view, create.erb
+ }
+ break;
+
+ default:
+ renderErrorResponse(Tf::NotFound);
+ break;
+ }
+}
+
+void BlogController::save(const QString &id)
+{
+ int res;
+
+ switch (request().method()) {
+ case Tf::Get:
+ service.edit(session(), id.toInt()); // Calls the service
+ render();
+ break;
+ case Tf::Post:
+ res = service.save(request(), session(), id.toInt()); // Calls the service
+ if (res > 0) {
+ // Save completed
+ redirect(urla("show", id)); // Redirects to /blog/show
+ } else if (res < 0) {
+ // Failed
+ render(); // Renders the view, save.erb
+ } else {
+ // Retry
+ redirect(urla("save", id)); // Redirects to /blog/save
+ }
+ break;
+ default:
+ renderErrorResponse(Tf::NotFound);
+ break;
+ }
+}
+
+void BlogController::remove(const QString &id)
+{
+ switch (request().method()) {
+ case Tf::Post:
+ service.remove(id.toInt()); // Calls the service
+ redirect(urla("index")); // Redirects to /blog/index
+ break;
+ default:
+ renderErrorResponse(Tf::NotFound);
+ break;
+ }
+}
+
+// Don't remove below this line
+T_DEFINE_CONTROLLER(BlogController)
+```
+
+In the service class, write the original logic that should be processed in the request, so business logic.
+It can process the model object retrieved from the database and send it to the view, or it can save the data retrieved from the request to the database via the model object. You can also validate the form data.
+
+```c++
+void BlogService::index()
+{
+ auto blogList = Blog::getAll(); // Gets a list of all Blog objects
+ texport(blogList); // Sends the data to the view
+}
+
+void BlogService::show(int id)
+{
+ auto blog = Blog::get(id); // Gets the Blog object by primary key
+ texport(blog); // Sends the data to the view
+}
+
+int BlogService::create(THttpRequest &request)
+{
+ auto items = request.formItems("blog"); // Gets the incoming form data
+ auto model = Blog::create(items); // Creates the Blog object
+
+ if (model.isNull()) {
+ QString error = "Failed to create."; // Error message
+ texport(error);
+ return -1;
+ }
+
+ QString notice = "Created successfully.";
+ tflash(notice); // Sets a flash message
+ return model.id();
+}
+
+void BlogService::edit(TSession& session, int id)
+{
+ auto model = Blog::get(id); // Gets the Blog object
+ if (!model.isNull()) {
+ session.insert("blog_lockRevision", model.lockRevision()); // Stores the lock revision to the session
+ auto blog = model.toVariantMap();
+ texport(blog); // Sends to the view
+ }
+}
+
+int BlogService::save(THttpRequest &request, TSession &session, int id)
+{
+ int rev = session.value("blog_lockRevision").toInt(); // Gets the lock revision
+ auto model = Blog::get(id, rev); // Gets a Blog object
+
+ if (model.isNull()) {
+ QString error = "Original data not found. It may have been updated/removed by another transaction.";
+ tflash(error);
+ return 0;
+ }
+
+ auto blog = request.formItems("blog"); // Gets the form data
+ model.setProperties(blog); // Sets the form data
+ if (!model.save()) { // Saves the object to DB
+ texport(blog);
+ QString error = "Failed to update.";
+ texport(error);
+ return -1;
+ }
+
+ QString notice = "Updated successfully.";
+ tflash(notice);
+ return 1;
+}
+
+bool BlogService::remove(int id)
+{
+ auto blog = Blog::get(id); // Gets a Blog object
+ return blog.remove(); // Removes it from DB
+}
+```
+
+Lock revision is used to realize the optimistic locking. See "model", which comes later in this chapter, for more information.
+
+As you can see, you can use the texport method to pass data to the view (template). The argument for this texport method is a QVariant object. QVariant can be any type, so int, QString, QList, and QHash can pass any object. For more details on QVariant, please refer to the Qt documentation.
+
+## View Mechanism
+
+Two template systems have been incorporated into TreeFrog so far. These are the proprietary system (called Otama) and ERB. As is familiar from Rails, ERB is used for embedding into HTML.
+
+The default view that is automatically generated by the generator is an ERB file. So, let's take a look at the contents of index.erb. As you can see, the C++ code is surrounded by <% … %>. When the render method is called from the index action, the content of index.erb is returned as the response.
+
+```
+
+<%#include "blog.h" %>
+
+
+
+ <%= controller()->name() + ": " + controller()->activeAction() %>
+
+
+
Listing Blog
+
+<%== linkTo("New entry", urla("entry")) %>
+
+
+
+
ID
+
Title
+
Body
+
+<% tfetch(QList, blogList); %>
+<% for (const auto &i : blogList) { %>
+
+```
+
+**Another template system**
+
+Otama is a template system that completely separates the presentation logic from the templates. The template is written in HTML and a "mark" element is inserted as the start tag of the section to be rewritten dynamically. The presentation logic file, written in C++ code, provides the logic in relation to the "mark".
+
+The following example is a file, _index.html_, that is generated by the generator when it is specified in the Otama template system. This can include the file data, but you will see, if you open it in your browser as it is, because it uses HTML5, the design does not collapse at all without the data.
+
+```
+
+
+
+
+
+
+
+
+
+
+```
+
+A custom attribute called 'data-tf' is used to turn on the "mark". This is a Custom Data Attribute as defined in HTML5. A string beginning with "@" is used as the value for the "mark".
+
+Next, let's look at the index.otm corresponding to the presentation logic.
+The mark, which links to the associated logic, is declared in the above template, and continues in effect until a blank line is encountered. The logic is contained in the C++ part of the code.
+
+Operators (such as == ~ =) are also used. The operators control different behaviors (for more information see the following chapters).
+
+```c++
+#include "blog.h" ← This is as it is C++ code to include the blog.h
+@head_title ~= controller()->controllerName() + ": " + controller()->actionName()
+
+@for :
+tfetch(QList, blogList); /* Declaration to use the data passed from the controller */
+for (QListIterator it(blogList); it.hasNext(); ) {
+ const Blog &i = it.next(); /* reference to Blog object */
+ %% /* usually, for loop statements, to repeat the child and elements */
+}
+
+@id ~= i.id() /* assigns the results of i.id() to the content of the element marked with @id */
+
+@title ~= i.title()
+
+@body ~= i.body()
+
+@linkToShow :== linkTo("Show", urla("show", i.id())) /* replaces the element and child elements with the results of linkTo() */
+
+@linkToEdit :== linkTo("Edit", urla("edit", i.id()))
+
+@linkToRemove :== linkTo("Remove", urla("remove", i.id()), Tf::Post, "confirm('Are you sure?')")
+```
+
+The Otama operators, (and their combinations) are fairly simple:
+\~ (tilde) sets the content of marked elements to the result of the right-hand side,
+\= output the HTML escape, therefore ~= sets the content of the element to the results of the right-hand side then HTML-escape, if you don't want to escape HTML, you can use ~==.
+
+\: (colon) replaces the result of the right-hand child elements and the elements that are marked, therefore :== replaces the element without HTML escape.
+
+### Passing Data from the Service or the Controller to the View
+
+In order to use the exported data (objects) in the view, you need to declare its variables by the tfetch() function. For the argument, specify type of the variable and the variable name. The variables are the same state as immediately before the specified variables are exported, and can be used exactly the same way as a normal variable of C++.
+
+Here is an example in use :
+
+```
+Service side :
+ int hoge;
+ hoge = ...
+ texport(hoge);
+
+View side :
+ tfetch(int, hoge);
+```
+
+The Otama system, generates the C++ code based on the presentation file and the template file. Internally, tmake is responsible for processing it. After that the code is compiled, with the shared library as one view, so, the operation is very fast.
+
+#### HTML Glossary
+
+An HTML element consists of three components, a start tag, the content, end an tag. For example, in the typical HTML element,
+"\
Hello\
", \
is the start tag, Hello is the content, and \
is the end tag.
+
+## Model and ORM
+
+In TreeFrog, a model object is **a data entity that can be persist and represents a concept**, and is a small wrapper around an ORM object. The model object contains the ORM object, which is a has-a relationship (naturally you can create such a model with two or more ORM objects). Since it uses "ORM = Object Model" by default in other framework, in this respect TreeFrog differs from the others.
+
+An O/R mapper named SqlObject is included by default in TreeFrog. Since C++ is a statically typed language, type declaration is required. Let's take a look at the SqlObject file generated by blogobject.h.
+
+There is charm codes, but the field in the table is declared as a public member variable. It is close to the actual structure, but can be used by CRUD or an equivalent method, (create, findFirst, update, remove). These methods are defined in the TSqlORMapper class and in the TSqlObject class.
+
+```c++
+class T_MODEL_EXPORT BlogObject : public TSqlObject, public QSharedData
+{
+public:
+ int id {0};
+ QString title;
+ QString body;
+ QDateTime created_at;
+ QDateTime updated_at;
+ int lock_revision {0};
+
+ enum PropertyIndex {
+ Id = 0,
+ Title,
+ Body,
+ CreatedAt,
+ UpdatedAt,
+ LockRevision,
+ };
+
+ int primaryKeyIndex() const override { return Id; }
+ int autoValueIndex() const override { return Id; }
+ QString tableName() const override { return QLatin1String("blog"); }
+
+private: /*** Don't modify below this line ***/
+ Q_OBJECT
+ Q_PROPERTY(int id READ getid WRITE setid)
+ T_DEFINE_PROPERTY(int, id)
+ Q_PROPERTY(QString title READ gettitle WRITE settitle)
+ T_DEFINE_PROPERTY(QString, title)
+ Q_PROPERTY(QString body READ getbody WRITE setbody)
+ T_DEFINE_PROPERTY(QString, body)
+ Q_PROPERTY(QDateTime created_at READ getcreated_at WRITE setcreated_at)
+ T_DEFINE_PROPERTY(QDateTime, created_at)
+ Q_PROPERTY(QDateTime updated_at READ getupdated_at WRITE setupdated_at)
+ T_DEFINE_PROPERTY(QDateTime, updated_at)
+ Q_PROPERTY(int lock_revision READ getlock_revision WRITE setlock_revision)
+ T_DEFINE_PROPERTY(int, lock_revision)
+};
+```
+
+There are methods to query and update the primary key in the TreeFrog's O/R mapper, but the primary key SqlObject can have only one return primaryKeyIndex() method. Therefore, any table with multiple primary keys should be corrected to return one only. It is also possible to issue more complex queries by using the TCriteria class condition. Please see following chapters for details.
+
+Next, let's look at the model.
+The setter/getter for each property and static method of generation/acquisition of the object are defined. The parent class TAbstractModel defines the methods to save and to remove, because of this, the Blog class is equipped with the CRUD methods (_create, get, save, remove_) .
+
+```c++
+class T_MODEL_EXPORT Blog : public TAbstractModel
+{
+public:
+ Blog();
+ Blog(const Blog &other);
+ Blog(const BlogObject &object); // constructor made from the ORM object
+ ~Blog();
+
+ int id() const; // The following lines are the setter/getter
+ QString title() const;
+ void setTitle(const QString &title);
+ QString body() const;
+ void setBody(const QString &body);
+ QDateTime createdAt() const;
+ QDateTime updatedAt() const;
+ int lockRevision() const;
+ Blog &operator=(const Blog &other);
+
+ bool create() { return TAbstractModel::create(); }
+ bool update() { return TAbstractModel::update(); }
+ bool save() { return TAbstractModel::save(); }
+ bool remove() { return TAbstractModel::remove(); }
+
+ static Blog create(const QString &title, const QString &body); // object creation
+ static Blog create(const QVariantMap &values); // object creation from Hash
+ static Blog get(int id); // Gets object specified by ID
+ static Blog get(int id, int lockRevision); // Gets object specified by ID and lockRevision
+ static int count(); // Returns the amount of blog data items
+ static QList getAll(); // Gets all model objects
+ static QJsonArray getAllJson(); // Gets all model objects in JSON style
+
+private:
+ QSharedDataPointer d; // Holds the pointer of the ORM object
+
+ TModelObject *modelData();
+ const TModelObject *modelData() const;
+};
+
+Q_DECLARE_METATYPE(Blog)
+Q_DECLARE_METATYPE(QList)
+```
+
+Despite the fact that the number of code steps automatically generated by the generator is not high, all the basic functions are covered.
+
+Of course, automatically generated code is not perfect. Real life applications may need to be more complex. The code may not be sufficient as generated, thus some reworking may be necessary. Nevertheless, the generator will save a little time and effort in writing code.
+
+In the background, the code as described above also functions to provide; CSRF measures with cookie tampering check, optimistic locking, and token authentication against SQL Injection. If you are interested, please look into the source.
+
+## Video Demo – Sample Blog Application Creation
+
+
+
+[](https://www.youtube.com/watch?v=M_ZUPZzi9V8)
+
+
diff --git a/docs/de/user-guide/view/erb.md b/docs/de/user-guide/view/erb.md
new file mode 100644
index 000000000..25be898b8
--- /dev/null
+++ b/docs/de/user-guide/view/erb.md
@@ -0,0 +1,339 @@
+---
+title: ERB
+page_id: "070.010"
+---
+
+## ERB
+
+Originally, ERB was a library for embedding Ruby script into text documents. It has been adopted as (one of the) template engines, such as Rails, that you can embed code in HTML between the tags likes these: <% … %>.
+
+In the same way, TreeFrog Framework uses tags <% … %> as well to embed C++ code. For convenience, I'll refer to this implementation as ERB as well.
+
+First, I'll make sure that the items in the configuration file *development.ini* are as follows. Unless you've changed from the default, they should be.
+
+```
+ TemplateSystem=ERB
+```
+
+Then, when you generate a view in the command generator, the ERB template format will be generated. File name of the template that is generated must follow the rule that it should all be in lower case.
+
+```
+ views/Controller-name/Action-name.erb (In lower case)
+```
+
+If you want to add a new template, please follow the same naming convention.
+
+
+## Relationship of View and Action
+
+I would like to review the relationship between view and action. As an example, when the bar action of the Foo controller calls the render() method without arguments, the content of the following template will be output.
+
+```
+ views/foo/bar.erb
+```
+
+If you call the render() method with an argument, the contents of the appropriate template will be output.
+
+You can add template files as you like. But consider, once you have added a new one (or several), you must run the following command once in the view directory:
+
+```
+ $ cd views
+ $ make qmake
+```
+
+That's all that was needed to do in order to add the new template which will has been added to the makefile entry of the build.
+Remember to reflect the new template that you've added in the shared library.
+
+##### In brief: After you have added a template file, use the "make qmake" command.
+
+## To Output a String
+
+We are going to the output the string "Hello world". There are two ways to do this. First, we can use the following method:
+
+```
+ <% eh("Hello world"); %>
+```
+
+This eh() method prints the string using the HTML escape for cross-site scripting protection. If you do not want to use escape processing, use the echo() method instead.
+
+Another way is to use the notation <%= … %>. This produces exactly the same results as using the eh() method does.
+
+```
+ <%= "Hello world" %>
+```
+
+Again if you do not want to use escape, you can use <%== … %> which gives exactly the same results as using the echo() method.
+
+```
+ <%== "
Hello world
" %>
+```
+
+**Note:**
+When you write <%= … %> in the original (eRuby) specification, it outputs a string WITHOUT HTML escape. In TreeFrog, the idea is that by using the shorter code for indicating HTML escape, safety is increased, based on the possibility that extra bits of code can easily be omitted in error. It seems to be becoming the mainstream in recent years.
+
+## Display of a Default Value
+
+If a variable is an empty string, let's display the default value as an alternative.
+By writing as follows, if the variable *str* is empty, then the string "none" is displayed.
+
+```
+ <%= str %|% "none" %>
+```
+
+## To Use the Object Passed from the Controller
+
+In order to display the object that is exported from the controller by the texport() method, first declare type (class) and variable names using the the tfetch() macro or T_FETCH macro. We'll refer to this operation as 'fetch'.
+
+```
+ <% tfetch(Blog, blog); %>
+ <%= blog.title %> ← output tha value of blog.title
+```
+
+The variable (object) that has been fetched, can be accessed later in the same file. In other words, it becomes a local variable.
+
+You might ask if fetch processing has to be processed each time of using, but you could see that the fetch processing does not have to be run every time you want to use the variable.
+
+The fetched object is a local variable in a function. Therefore, if we fetched the same object twice, because the variables are the same we would have defined twice, giving an error at compile time. Of course, it would not be a compile-time error if we divided the block, but it probably would not make much sense to do so.
+
+##### In brief: Use the fetch case only once.
+
+If you export objects of the type int and QString type, then you can only output in the tehex() function. Fetch processing eliminates the need for it to be this way.
+
+```
+ <% tehex(foo); %>
+```
+
+Understand that tehex() function as a combination of the eh() and the fetch() method. There is a difference in defining between fetching and local variables, as you can see in here, function variable (*foo* in this example) outputs the value without defining.
+
+If you do not want to escape the HTML processing, use the techoex() function, which is a combination of echo() and fetch() methods. In the same way, the variable is not defined.
+
+In addition, there is another way to export the output objects. You can use the code <=$ .. %>. Note that there must be no space between '$' (dollar) and '=' (equal).
+This produces exactly the same result.
+
+```
+ <%=$ foo %>
+```
+
+Codes have been considerably simplified.
+This means that you can replace the tehex() method with the "=$" code.
+Similarly, <% techoex(..); %> can be rewritten in the notation <==$ .. %>.
+
+To sum up, to export an object of int type or QString type, I think it's better to output using the notation <=$ .. %>, unless you want to output just once (in which case, use the fetch process ).
+
+**In brief: Use \<=\$ .. %> to export objects that do not output only once.**
+
+## How to Write Comments
+
+The following is an example of how to write a comment. Nothing will be output as HTML. However, its contents will remain in the C++ code.
+
+```
+ <%# comment area %>
+```
+
+After the C++ code is placed in the views/_src directory, it is compiled. Look here if you want to refer to the C++ code.
+
+## Include Files
+
+If you use a class, such as a model, in the ERB template, you will need to include the header file in the same way as with C++. Note that it is not automatically included.
+Include these next:
+
+```
+ <%#include "blog.h" %>
+```
+
+Note that there must be no space between '#' and 'include'. In this example, the blog.h file is to be included.
+
+Remember that the template is converted to C++ code as it is, so don't forget to include the template file.
+
+## Loop
+
+Let's write a loop to use on a list. For example, take the list blogList which is made up of objects called Blog, it looks like this (if it is exporting an object, do the fetch processing in advance):
+
+```
+ <% QListIterator i(blogList);
+ while ( i.hasNext() ) {
+ const Blog &b = i.next(); %>
+ ...
+ <% } %>
+```
+
+You can use the foreach statement from Qt which makes coding shorter:
+
+```
+ <% foreach (Blog b, blogList) { %>
+ ...
+ <% } %>
+```
+
+This looks more like C++.
+
+## Creating an \ Tag
+
+To create an \ tag, use the linkTo() method:
+
+```
+ <%== linkTo("Back", QUrl("/Blog/index")) %>
+ ↓
+ Back
+```
+
+In the linkTo() method, other arguments can be specified; see the [API reference](http://treefrogframework.org/tf_doxygen/classes.html){:target="_blank"} for more information.
+
+You could also use the url() method to specify a URL. Specify the controller name, with the url as the first argument, and the action name as the second argument.
+
+```
+ <%== linkTo("Back", url("Blog", "index")) %>
+ ↓
+ Back
+```
+
+If the template is on the same controller, you use the urla() method and specify only the action name:
+
+```
+ <%== linkTo("Back", urla("index")) %>
+ ↓
+ Back
+```
+
+Using JavaScript, the link and confirmation dialog can be written as follows:
+
+```
+ <%== linkTo(tr("Delete"), urla("remove", 1), Tf::Post, "confirm('Are you sure?')") %>
+ ↓
+ Delete
+```
+
+Now let's add an attribute to the tag, using the THtmlAttribute class:
+
+```
+ <%== linkTo("Back", urla("index"), Tf::Get, "", THtmlAttribute("class", "menu")) %>
+ ↓
+ Back
+```
+
+You can use the short a() method code to generate the same THtmlAttribute output:
+
+```
+ <%== linkTo("Back", urla("index"), Tf::Get, "", a("class", "menu")) %>
+```
+
+If there is more than one attribute, use '\|' operator:
+
+```
+ a("class", "menu") | a("title", "hello")
+ ↓
+ class="menu" title="hello"
+```
+
+By the way, there is the anchor() method, that aliases the linkTo() method; they can be used in exactly the same way.
+
+In addition, many other methods are available, see the [API Document](http://treefrogframework.org/tf_doxygen/classes.html){:target="_blank"}
+
+## Form
+
+We are going to post the data to the server from a browser form. In the following example, we use the formTag() method to post data to create action on the same controller.
+
+```
+ <%== formTag(urla("create"), Tf::Post) %>
+ ...
+ ...
+
+```
+
+You may think that you can do the same thing by describing the form tag, rather than the formTag() method, but when you do use the method it means that the framework can do CSRF measures. From a security point of view, we should do so. To enable this CSRF measures, please set the items as follows in the configuration file application.ini.
+
+```
+ EnableCsrfProtectionModule=true
+```
+
+This framework makes it illegal to guard post data. However, following various repeated tests during development, of course you can disable the protection temporarily.
+
+For more information on CSRF measures, see also the chapter [security]({{ site.baseurl }}/en/user-guide/security/index.html){:target="_blank"}.
+
+## Layout
+
+The layout is a template on which to outline the design commonly used in the site. It is not possible to place an HTML element freely in the layout, except in the header part, menu section, and footer section.
+
+There are four ways to interact with the layout when the controller requests view, as follows:
+
+1. Set the layout for each action.
+2. Set the layout for each controller.
+3. Use the default layout.
+4. Do not use layout.
+
+Only one layout is used when drawing the view, but a different layout can be used if the above list gives it a higher priority. So, for example, this means that rather than "layout that is set for each controller," being used, the rule "layout is set for each action" takes precedence.
+
+Let's take the example of a very simple layout (as per the following). It is saved with the extension .erb. The location of the layout is the view/layouts directory.
+
+```
+
+
+
+
+ Blog Title
+
+ ...
+<%== yield() %>
+ ...
+
+```
+
+The important part here is the line; <%== yield(); %>. This line outputs the contents of the template. In other words, when the render() method is called, the content of the template will be merged into the layout.
+
+By using a layout like this, you can put together a common design, such as headers and footers, for the site. Changing the design of the site then becomes much easier, because all you need to change is the layout.
+
+##### In brief: Layout is the overall outline for the site design.
+
+Now, I will describe each method to set the layout.
+
+**1.Set the layout for each action**
+
+You can set the layout name as the second argument of the render() method when it is called in the action.
+This example layout simplelayout.erb is used here.
+
+```c++
+render("show", "simplelayout");
+```
+
+Now, the contents of the show template, merged into the layout of simplelayout, will be returned as a response.
+
+**2.Set the layout for each controller**
+
+In the constructor of the controller, call the setLayout() method, and specify the layout name as an argument.
+
+```c++
+setLayout("basiclayout"); // basiclayout.erb the layout used
+```
+
+**3.Use the default layout**
+
+The file application.erb is the default layout file. If you do not specify a particular layout, this default layout is used.
+
+
+**4.Do not use layout**
+
+If none of the above three conditions are met, no layout is used. In addition, if you want to specify that a layout is not used, use an action to call the function setLayoutDisabled(true).
+
+## Partial Template
+
+If you viewing a website, you will often notice an area of the page which is constant, that is it shows the same content on multiple pages. Perhaps it's an advertising area, or some kind of toolbar.
+
+To work on a Web application in cases like this, besides the methods discussed above for including such an area in the layout, there is also a way to share content by cutting the area into a "partial" templates.
+
+First, cut out the part you want to use on multiple pages, then save it to the views/partial directory as a template, with the .erb extension. We can then draw it with the renderPartial() method.
+
+```
+ <%== renderPartial("content") %>
+```
+
+The contents of *content.erb* are embedded into the original template and then output. In the partial template, you can output the value of export objects as well as the original templates.
+
+From the fact that both are types of merging, the layout and partial template should seem very familiar. But what can you do is to use them in a different way.
+
+My opinion is that it is good way to define the layout for sections such as footer and header that are always present on the page, and to use additional partial templates to display the parts that are often but not always displayed on the page.
+
+##### In brief: Define areas of your layout that have persistent and not persistent content and put them into partial templates.
diff --git a/docs/de/user-guide/view/index.md b/docs/de/user-guide/view/index.md
new file mode 100644
index 000000000..dc3e97c15
--- /dev/null
+++ b/docs/de/user-guide/view/index.md
@@ -0,0 +1,19 @@
+---
+title: View
+page_id: "070.0"
+---
+
+## View
+
+The role of view in a Web application is to generate an HTML document from a response. The developer creates each template for an HTML document to be embedded in a predetermined portion of the variable passed from the controller (model).
+
+There are two template systems so far adopted into the TreeFrog Framework. These are Otama and ERB. In both systems you can output the value dynamically using the template, and perform loops and conditional branching.
+
+The ERB system, such as in Ruby, is used to embed the template code in the program (library). While there are benefits in that it is easy to understand as a mechanism, it is difficult to check or change the Web design.
+
+Otama is a template system that completely separates the presentation logic and the templates. The advantage is that checking or changing the Web Design is easy, and programmers and designers are better able to collaboration. The disadvantage is that a little more complex mechanism is required, and that there will be a slight learning cost.
+
+Performance is the same in either. When the codes are built, the templates are compiled after it is converted to C++ code. One shared library (dynamic link library) is created, so both run faster. After that, it depends on user's description of the code.
+
+* [To the chapter of ERB template system >>]({{ site.baseurl }}/en/user-guide/view/erb.html){:target="_blank"}
+* [To the chapter of Otama template system >>]({{ site.baseurl }}/en/user-guide/view/otama-template-system.html){:target="_blank"}
\ No newline at end of file
diff --git a/docs/de/user-guide/view/otama-template-system.md b/docs/de/user-guide/view/otama-template-system.md
new file mode 100644
index 000000000..568a2808c
--- /dev/null
+++ b/docs/de/user-guide/view/otama-template-system.md
@@ -0,0 +1,402 @@
+---
+title: Otama Template System
+page_id: "070.020"
+---
+
+## Otama Template System
+
+Otama is a template system that completely separates the presentation logic from the templates. It is a system made especially for the TreeFrog Framework.
+
+Views are created for the Otama system when the configuration file (development.ini) is edited as the following and then the generator makes a scaffolding.
+
+```
+ TemplateSystem=Otama
+```
+
+The template is written in full HTML (with the .html file extension). A "mark" is used for the tag elements where logic code is to be inserted. The presentation logic file (.otm) is written with the associated C++ code, and the mark. This will be then automatically converted to C++ code when the shared view library is built.
+
+
+
+Basically, a set of presentation logic and template are made for every action. The file names are [action name].html and [action name].otm (case-sensitive). The files are placed in the "views/controller-name/" directory.
+
+Once you have created a new template, in order for this to be reflected in the view shared library, you will need to run "make qmake" in the view directory
+
+```
+ $ cd views
+ $ make qmake
+```
+
+If you have not already done so, it is recommended that you read the ERB chapter before continuing with this chapter, since there is much in common between the two template systems. Also, there is so much to learn about the Otama system that knowing ERB in advance will make it easier to understand.
+
+## Output a String
+
+We are going to the output of the statement "Hello world".
+On the template page, written in HTML , use a custom attribute called data-tf to put a "mark" for the element. The attribute name must start with "@". For example, we write as follows:
+
+```
+
+```
+
+We've used paragraph tags (\
\
) around the @hello mark.
+In the mark you may only use alphanumeric characters and the underscore '_'. Do not use anything else.
+
+Next, we'll look at the presentation logic file in C++ code. We need to associate the C++ code with the mark made above. We write this as follows:
+
+```
+ @hello ~ eh("Hello world");
+```
+
+We then build, run the app, and then the view will output the following results:
+
+```
+
Hello world
+```
+
+The tilde (~) that connects the C++ code with the mark that was intended for the presentation logic means effectively "substitute the contents of the right side for the content of the element marked". We remember that the eh() method outputs the value that is passed.
+
+In other words, the content between the p tags (blank in this case) is replaced with "Hello world". The data-tf attribute will then disappear entirely.
+
+In addition, as an alternative way of outputting the same result, it's also possible to write as follows:
+
+```
+ @hello ~= "Hello world"
+```
+
+As in ERB; The combination of ~ and eh() method can be rewritten as '~='; similarly, the combination of ~ and echo() method can be rewritten as '~=='.
+
+Although we've output a static string here, in order to simplify the explanation, it's also possible to output a variable in the same way. Of course, it is also possible to output an object that is passed from the controller.
+
+##### In brief: Place a mark where you want to output a variable. Then connect the mark to the code.
+
+## Otama Operator
+
+The symbols that are sandwiched between the C++ code and the mark are called the Otama operator.
+
+Associate C++ code and elements using the Otama operator, and then decide how these should function. In the presentation logic, note that there must be a space on each side of the Otama operator.
+
+This time, we'll use a different Otama operator. Let's assume that presentation logic is written as the following (colon).
+
+```
+ @hello : eh("Hello world");
+```
+
+The Result of View is as follows:
+
+```
+ Hello world
+```
+
+The p tag has been removed. This is because the colon has the effect of "replace the whole element marked", with this result. Similar to the above, this could also be written as follows:
+
+```
+ @hello := "Hello world"
+```
+
+## Using an Object Passed from the Controller
+
+In order to display the export object passed from the controller, as with ERB, you can use it after fetching by tfetch() macro or T_FETCH() macro. When msg can export an object of QString type, you can describe as follows:
+
+```
+ @hello : tfetch(QString, msg); eh(msg);
+```
+
+As with ERB, objects fetched are defined as a local variable.
+
+Typically, C++ code will not fit in one instruction line. To write a C++ code of multiple rows for one mark, write side by side as normal but put a blank line at the end. The blank line is considered to be one set of the parts of the mark. Thus, between one mark and the next a blank line (including a line with only blank characters) acts as a separator in the presentation logic.
+
+##### In brief: logic is delimited by an empty line.
+
+Next, we look at the case of wanting to display an export object in two different locations. In this case, if you describe it at #init, it will be called first (fetched). After that, it can be used freely in the presentation logic. It should look similar to the following:
+
+```
+ #init : tfetch(QString, msg);
+
+ @foo1 := msg
+
+ @foo2 ~= QString("message is ") + msg
+```
+
+With that said, for exporting objects that are referenced more than once, use the fetch processing at *#init*.
+
+Here is yet another way to export output objects.
+Place "$" after the Otama operator. For example, you could write the following to export the output object called *obj1*.
+
+```
+ @foo1 :=$ obj1
+```
+
+This is, output the value using the eh() method while fetch() processing for obj1. However, this process is only an equivalent to fetch processing, the local variable is not actually defined.
+
+To obtain output using the echo() method, you can write as follows:
+
+```
+ @foo1 :==$ obj1
+```
+
+Just like ERB.
+
+##### In brief: for export objects, output using =$ or ~=$.
+
+## Loop
+
+Next, I will explain how to use loop processing for repeatedly displaying the numbers in a list.
+In the template, we want a text description.
+
+```
+
+
+
+
+
+```
+
+That is exported as an object in the list of Blog class named blogList. We want to write a loop using a for statement. The while statement will also be similar.
+
+```
+ @foreach :
+ tfetch(QList, blogList); /* Fetch processing */
+ for (auto &b, blogList) {
+ %%
+ }
+
+ @id ~= b.id()
+
+ @title ~= b.title()
+
+ @body ~= b.body()
+```
+
+The %% sign is important, because it refers to the entire element (*@foreach*) of the mark. In other words, in this case, it refers to the element from \
up to \ tr\>. Therefore, by repeating the \
tags, the foreach statement which sets the value of each content element with *@id*, *@title*, and *@body*, results in the view output being something like the following:
+
+```
+
to POST data unless you have enabled the CSRF measures. It does not accept POST data but only describes the form tag in the template. We need to embed the secret information as a hidden parameter.
+
+We use the \
tag in the template. After putting the mark to the \
tag of the template, merge it with the content of what the formTag() method is outputting
+
+Template:
+
+```
+ :
+
+ :
+```
+
+Presentation logic:
+
+```
+ @form |== formTag( ... )
+```
+
+You'll be able to POST the data normally.
+
+For those who have enabled CSRF measures and want to have more details about security, please check out the chapter [security]({{ site.baseurl }}/en/user-guide/security/index.html){:target="_blank"}.
+
+## Erasing the Element
+
+If you mark *@dummy* elements in the template, it is not output as a view. Suppose you wrote the following to the template.
+
+```
+
+
Hello
+
message ..
+
+```
+Then, the view will make the following results.
+
+```
+
+
Hello
+
+```
+
+## Erasing the Tag
+
+You can keep a content and erase a start-tag and an end-tag only.
+For example, when using a layout, the \ tag is outputted by the layout file side, so you don't need to output it anymore on the template side, but leave the \ tag on the template side if you want your layout have based on HTML.
+Suppose you wrote the following to the template.
+
+```
+
+
Hello
+
+```
+
+Then, the view will make the following results.
+
+```
+
Hello
+```
+
+You use these when you want to keep it in the Web design, but erase it from the view.
+
+## Including the Header File
+
+We talked about the presentation logic template being converted to C++ code. The header and user-defined files will not be included automatically and you must write them by yourself. However, basic TreeFrog header files can be included.
+
+For example, if you want to include *user.h* and *blog.h* files, you would write these in at the top of the presentation logic.
+
+```
+ #include "blog.h"
+ #include "user.h"
+```
+
+All the same as the C++ code!
+Lines beginning with an #include string are moved directly to the code view.
+
+## Otama Operator
+
+The following table describes the Otama operator which we've been discussing.
+
+
+
+| Operator | Description | Remarks |
+|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
+| : | **Element replacement** The components and subcomponents that are markedwill be completely replaced and output by the string inside the eh() or echo() method which are on the right-hand side of this operator. | %% means the elements themselves that can be replaced.
+| ~ | **Content replacement** The content of marked elementswill be replaced and output by the string inside the eh() or echo() method which are on the right-hand side of this operator. | |
+| + | **Attribute addition** If you want to add an attribute to an element that is marked, use this operator plus a string inside the echo() method, which is supposed to be output on the right-hand side of this operator. | += is HTML escaping, perhaps not used that much. |
+| \|== | **Element merger** Based on the marked elements, the specified strings will be merged on the right-hand side of this operator. | '\|' and '\|=' are disabled. |
+
+
+
+Extended versions of these four operators are as follows.
+With the echo() statement and eh() statement no longer being needed, you'll be able to write shorter code.
+
+
+
+| Operator | Description |
+|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| := :== :=$ :==$ | Element replaced by an HTML escaped variable. Element replaced by a variable. Element replaced by an HTML escaped export object. Element replaced by an export object. |
+| ~= ~== ~=$ ~==$ | Content replaced by an HTML escaped variable. Content replaced by a variable. Content replaced by an HTML escaped export object. Content replaced by an export object. |
+| += +== +=$ +==$ | Add an HTML escaped variable to an attribute. Add a variable to an attribute. Add an HTML escaped export object to an attribute. Add an export object to an attribute. |
+| \|==$ | Element merged with an export object. |
+
+
+
+## Comment
+
+Please write in the form of /*.. */, if you want to write a comment in the presentation logic.
+
+```
+ @foo ~= bar /* This is a comment */
+```
+
+**Note:** In C++ the format used is "// .." but this can NOT be used in the presentation logic.
\ No newline at end of file
diff --git a/docs/de/user-guide/view/static-contents.md b/docs/de/user-guide/view/static-contents.md
new file mode 100644
index 000000000..30aa16c94
--- /dev/null
+++ b/docs/de/user-guide/view/static-contents.md
@@ -0,0 +1,97 @@
+---
+title: Static Contents
+page_id: "070.030"
+---
+
+## Static Contents
+
+Place static contents that is accessible from the browser in the *public* directory. Only save published files here.
+
+For example, assuming that an HTML file is in *public/sample.html*. When you access *http://URL:PORT/sample.html* from the browser, in case the application server (AP server) is running, its content will be displayed.
+
+After creating the skeleton of the application by using the generator command, the following subdirectories will be created.
+
+
+
+You can make subdirectories freely within the public directory.
+
+## Internet Media Type (MIME type)
+
+When the web server returns static content, the rule is to set the internet media type (MIME type) in the response's content-type header field. These are the strings such as "text/html" and "image/jpg". Using this information, the browser can determine the format in which the data has been sent.
+
+TreeFrog Framework returns the media type by using the file extension and referring to the defined content in the *config/initializers/internet_media_types.ini* file. In that file, line by line, file extensions and internet media types are defined and connected with "=". It is as in the following table.
+
+```
+ pdf=application/pdf
+ js=application/javascript
+ zip=application/zip
+ :
+```
+
+If the Internet media types don't cover your needs, you can add other types in this file. After doing so, you should restart the AP server to reflect the definition information that you added.
+
+## Error Display
+
+The AP server is always required to return some response even if some error or exception occurs. In these cases, the status codes for the error responses are defined in [RFC](http://www.ietf.org/rfc/rfc2616.txt){:target="_blank"}.
+In this framework, the contents of the following files will be returned as the response when an error or exception occurs.
+
+
+
+| Cause | Static File |
+|--------------------------|-----------------|
+| Not Found | public/404.html |
+| Request Entity Too Large | public/413.html |
+| Internal Server Error | public/500.html |
+
+
+
+By editing these static files, you can change what to display.
+
+By calling the function from the action as follows, you will be able to return the static file to indicate the error. In this way, when 401 is set as the status code of the response, the contents of *public/401.html* would be returned.
+
+```c++
+renderErrorResponse(401);
+```
+
+Furthermore, as another method of displaying an error screen into the browser, it is redirecting to the given URL.
+
+```c++
+redirect(QUrl("/401.html"));
+```
+
+## Send a File
+
+If you want to send a file from the controller, use the sendFile() method. As the first argument, specify the file path, and as the second argument, specify the content type. The file sent is not required to be in the *public* directory.
+
+```c++
+sendFile("filepath.jpg", "image/jpeg");
+```
+
+If you send a file in this function, then the file download process is implemented on the Web browser side. A dialog is displayed, asking if the user wants to open or to save the file. This function sends the file as HTTP response which it is the same treatment as the render() method. Therefore, the controller can no longer output the template by the render() method.
+
+By the way, as for the file path here, if you specify an absolute path, it would ensure that it will be found. If you use the Tf::app()->webRootPath() function, you can obtain the absolute path to the application directory route, so you can easily create the absolute path to the file. In order to use this function, please include TWebApplication in the header file.
+
+```c++
+#include
+```
+
+## Send Data
+
+To send the data into the memory, instead to a file, you can use the sendData() method as follows.
+
+```c++
+QByteArray data;
+data = ...
+sendFile(data, "text/plain");
+```
+
+You can omit the access process to reduce the overhead compared to the sendFile() method.
+Similarly, it means the file download operation is executed on the Web browser side, after that you cannot call the render() method (it would not work if you did).
\ No newline at end of file
diff --git a/docs/de/user-guide/websocket/index.md b/docs/de/user-guide/websocket/index.md
new file mode 100644
index 000000000..3c02b80bb
--- /dev/null
+++ b/docs/de/user-guide/websocket/index.md
@@ -0,0 +1,265 @@
+---
+title: WebSocket
+page_id: "090.0"
+---
+
+## WebSocket
+
+WebSocket is a communication standard that performs bidirectional communication between server and client, and is widely supported by browsers.
+
+HTTP repeatedly establishes connections and disconnections for every request that is made and it is not supposed to establish connections for a long time.
+WebSocket, on the other hand, maintains the TCP connection once it has been established successfully. During a persisting connection, messages can be sent from either side. Because it is assumed that a connection will be long-lasting, so-called **Ping/Pong** frames are defined to confirm the other side's life and death.
+
+Additionally, since the connection is stateful (maintaining an established connection), you don't need to return the session ID by using a cookie.
+
+##### In short: WebSocket is a stateful and bidirectional communication
+
+In case the client is a browser, the connection will be lost, if you move to another page or if the WebSocket connection established for a page is closed.
+
+Since WebSocket in the browser is implemented with JavaScript, it is natural that the Websocket connection will be lost if its context (object) disappears, therefore it can be considered that the timing of the disconnect is associated with the page transition. In practice it is considered that there are not many cases in which a connection is actually long-lasting.
+
+Now, let's try to prepare a WebSocket that is compatible with the browser and write some JavaScript.
+
+First, we will generate a WebSocket object. As for the parameters, pass in the URL starting with *ws://* or *wss://*.
+The connection processing is performed at the time of creation.
+
+The following event handlers can be registered for the WebSocket object:
+
+
+
+For more insight details, please visit [http://www.w3.org/TR/websockets/](http://www.w3.org/TR/websockets/){:target="_blank"}.
+
+## Make a chat application
+
+Let's make a chat application based on these handlers.
+The main function of this application is as follow: the user can enter his name and a message into a very basic HTML form. After the user has clicked the "send" button, the application will send the data to a server and stores it inside a database. Whenever any visitor of this application accesses the Web page, for example, the most recent 30 messages will be delivered to the visitor and displayed in the chat window.
+
+We will also talk about how to send messages only to persons who have *subscribed* to a specific *topic*.
+
+Now let's start with the implementation, starting with the client side. **Note:** the following example uses [jQuery](https://jquery.com/){:target="_blank"}.
+
+**HTML (excerpt)**
+Save it as public/index.html.
+
+```
+
+
+
+Name
+
+
+```
+
+Here is an example made with JavaScript.
+
+```js
+$(function(){
+ // create WebSocket to 'chat' endpoint
+ ws = new WebSocket("ws://" + location.host + "/chat");
+
+ // message received
+ ws.onmessage = function(message){
+ var msg = escapeHtml(message.data);
+ $("#log").append("
" + msg + "
");
+ }
+
+ // error event
+ ws.onerror = function(){
+ $("#log").append("[ Error occurred. Try reloading. ]");
+ }
+
+ // onclose event
+ ws.onclose = function(){
+ $("#log").append("[ Connection closed. Try reloading. ]");
+ }
+});
+// Sending as one message containing 'Name' and 'Time'
+function sendMessage() {
+ if ($('#msg').val() != '') {
+ var name = $.trim($('#name').val());
+ if (name == '') {
+ name = "(I'm John Doe)";
+ }
+ name += ' : ' + (new Date()).toISOString() + '\n';
+ ws.send(name + $('#msg').val());
+ $('#msg').val(''); // clear
+ }
+}
+```
+
+Next, let's implement the server side by using scaffold.
+
+```
+ $ tspawn new chatapp
+ created chatapp
+ created chatapp/controllers
+ created chatapp/models
+ :
+```
+
+Create an endpoint for the WebSocket interaction.
+This is made with the name ('chat' in this example) set as the path of URL passed when generating the JavaScript WebSocket object. Otherwise it will not work!
+
+```
+ $ cd chatapp
+ $ tspawn websocket chat
+ created controllers/applicationendpoint.h
+ updated controllers/controllers.pro
+ created controllers/applicationendpoint.cpp
+ :
+```
+
+The generated *chatendpoint.h* looks then as follows.
+There is no need to modify it in particular.
+
+```c++
+class T_CONTROLLER_EXPORT ChatEndpoint : public ApplicationEndpoint
+{
+public:
+ ChatEndpoint() { }
+ ChatEndpoint(const ChatEndpoint &other);
+protected:
+ bool onOpen(const TSession &httpSession); // open handler
+ void onClose(int closeCode); // close handler
+ void onTextReceived(const QString &text); // text receive handler
+ void onBinaryReceived(const QByteArray &binary); // binary receive handler
+};
+```
+
+**Explaining the onOpen() handler:**
+The HTTP session object at that time is passed in the *httpSession* argument. The endpoint is read only and its content cannot be changed (I may deal with this in the future).
+
+Instead, let's save the information here using the *WebSocketSession* object. Within each method of the endpoint class, the information can be retrieved using the *session()* method. By the way, since the information is stored in the memory, if you store data of a large size, memory will be compressed if the connection load increases.
+
+Furthermore, the WebSocket connection can be rejected if the return value of *onOpen()* is *false*. If you don't want to accept all connection requests, it is possible to implement some sort secret values stored in HTTP sessions, for example, accepting them only if they are correct.
+
+Next is the *chatendpoint.cpp*.
+We want to send the received text to all the subscribers. This can be done by using the *publication/subscription* (Pub/Sub) method.
+
+First, the recipient needs to subscribe to a certain "topic". When someone is sending a message to that "topic", that message will delivered to all its subscribers.
+
+The code for this behaviour looks like this:
+
+```c++
+#define TOPIC_NAME "foo"
+ChatEndpoint::ChatEndpoint(const ChatEndpoint &)
+ : ApplicationEndpoint()
+{ }
+
+bool ChatEndpoint::onOpen(const TSession &)
+{
+ subscribe(TOPIC_NAME); // Start subscription
+ publish(TOPIC_NAME, QString(" [ New person joined ]\n"));
+ return true;
+}
+
+void ChatEndpoint::onClose(int)
+{
+ unsubscribe(TOPIC_NAME); // Stop subscription
+ publish(TOPIC_NAME, QString(" [ A person left ]\n"));
+}
+
+void ChatEndpoint::onTextReceived(const QString &text)
+{
+ publish(TOPIC_NAME, text); // Send message
+}
+
+void ChatEndpoint::onBinaryReceived(const QByteArray &)
+{ }
+```
+
+### Build
+
+In this case, I will not use **VIEW**, so I will remove it from the build.
+Edit *chatapp.pro* as follows and save it.
+
+```
+ TEMPLATE = subdirs
+ CONFIG += ordered
+ SUBDIRS = helpers models controllers
+```
+
+Build command:
+
+```
+ $ qmake -r
+ $ make (nmake on Windows)
+ $ treefrog -d
+
+ (stop command)
+ $ treefrog -k stop
+```
+
+Let's start the browser and access *http://(host):8800/index.html*.
+
+Did it work properly?
+
+We are now publishing what we just have implemented, so the result should look like the following: [http://chatsample.treefrogframework.org/](http://chatsample.treefrogframework.org/){:target="_blank"}
+
+The following functions are added from the sample above:
+
+* 30 most recent messages are stored in DB
+* the message is sent immediately after connection (*onOpen()*)
+* adding some stylish CSS makes your application look good
+
+## Keep alive
+
+When the non-communication state lasts for a long time in a TCP session, communication devices, such as routers, will stop routing. In this case, even if you send a message from the server, it will not reach the client anymore.
+
+In order to avoid this, it is necessary to keep connection alive by periodically communicating. *Keep alive* in WebSocket is achieved by sending and receiving *Ping/Pong* frames.
+
+In TreeFrog, it is set by the return value of the *keepAliveInterval()* of the endpoint class. The time unit is in seconds.
+
+```c++
+int keepAliveInterval() const { return 300; }
+```
+
+If the value is 0, the keep-alive function will not work. The default is 0 (not keepalive).
+
+By keeping alive, you can check not only whether the communication path is valid, but also you can check that the host software is not down. However, the API that detects it is currently available (2015/6), but not implemented in TreeFrog yet.
+
+**Reference**
+tspawn HELP
+
+```
+ $ tspawn -h
+ usage: tspawn [args]
+ Type 'tspawn --show-drivers' to show all the available database drivers for Qt.
+ Type 'tspawn --show-driver-path' to show the path of database drivers for Qt.
+ Type 'tspawn --show-tables' to show all tables to user in the setting of 'dev'.
+ Type 'tspawn --show-collections' to show all collections in the MongoDB.
+
+ Available subcommands:
+ new (n)
+ scaffold (s) [model-name]
+ controller (c) action [action ...]
+ model (m) [model-name]
+ usermodel (u) [username password [model-name]]
+ sqlobject (o) [model-name]
+ mongoscaffold (ms)
+ mongomodel (mm)
+ websocket (w)
+ validator (v)
+ mailer (l) action [action ...]
+ delete (d)
+```
\ No newline at end of file