Changes for page Your First D2W Project

Last modified by Bastian Triller on 2013/01/12 00:43

From version 5.1
edited by Pascal Robert
on 2012/07/30 05:47
Change comment: There is no comment for this version
To version 6.1
edited by Pascal Robert
on 2012/07/30 09:12
Change comment: There is no comment for this version

Summary

Details

Page properties
Content
... ... @@ -4,10 +4,138 @@
4 4  
5 5  Now that our data model is in a framework and that we have a basic REST application working, we are going to build a DirectToWeb application to manage the blog system. But first, what is DirectToWeb (D2W)? D2W is a rules-based application model where you can change the behavior of the application by rules. D2W is perfect for "admin" apps, for applications that share a common model or for "**CRUD**" (**C{**}reate **R{**}ead **U{**}pdate **D{**}estroy) applications.
6 6  
7 -So like I said, we are going to build a D2W app that will allow us to update and create blog entries and authors. Let's start by creating a //Wonder D2W Application// in Eclipse: [[image:Capture d’écran 2012-07-29 à 14.22.22.png||border="1"]]
8 -Name it **D2WBlog**. The next step is to link the **BlogCommon** framework to the D2W app. To do so, right-click on **D2WBlog** and select **Build Path** > **Configure Build Path**.  [[image:Capture d’écran 2012-07-29 à 14.25.46.png||border="1"]]
7 +So like I said, we are going to build a D2W app that will allow us to update and create blog entries and authors. Let's start by creating a //Wonder D2W Application// in Eclipse:
9 9  
9 +[[image:Capture d’écran 2012-07-29 à 14.22.22.png||border="1"]]
10 +
11 +Name it **D2WBlog**. The next step is to link the **BlogCommon** framework to the D2W app. To do so, right-click on **D2WBlog** and select **Build Path** > **Configure Build Path**. 
12 +
13 +[[image:Capture d’écran 2012-07-29 à 14.25.46.png||border="1"]]
14 +
10 10  In the **Libraries** tab, click on **Add Library**. Select **WebObjects Frameworks** and click **Next**. Check **BlogCommon** and **H2PlugIn** from the list and click **Finish**. The **Libraries** tab should look like this:
16 +
11 11  [[image:Capture d’écran 2012-07-29 à 14.32.51.png||border="1"]]
12 12  
13 -It's time to run the app. Right-click on Application.java 
19 +It's time to run the app. Right-click on **Application.java** and select **Run As** > **WO Application**. By default, a D2W app will always display a login form and the login method is connected to a DirectAction that should handle the authentification. The default implementation of that DirectAction (the loginAction method in the DirectAction class) don't do anything special:
20 +
21 +{{code language="java"}}
22 +
23 +public WOActionResults loginAction() {
24 + String username = request().stringFormValueForKey("username");
25 + String password = request().stringFormValueForKey("password");
26 + return D2W.factory().defaultPage(session());
27 + }
28 +
29 +{{/code}}
30 +
31 +Just click the **Login** button and you will get into the application. Navigate in the application, but you will see that it don't do anything special and you don't see data. You can terminate the app (by clicking the red stop button in Eclipse's console).
32 +
33 +The first thing we will do is to make authentification to work. We don't have a password in our data model so authentification will only be done on the email address (yes, we know it's not very secure). The first thing we need to do is to store the logged author into the session so that we can access it from all pages. To do so, open the **Session** class and add the following code:
34 +
35 +{{code language="java"}}
36 +
37 +import er.extensions.foundation.ERXThreadStorage;
38 +
39 + private Author _author;
40 +
41 + public Author author() {
42 + return _author;
43 + }
44 +
45 + public void setAuthor(Author author) {
46 + _author = author;
47 + ERXThreadStorage.takeValueForKey(author(), "author");
48 + }
49 +
50 +{{/code}}
51 +
52 +Open the **DirectAction** class and rewrite the **loginAction** method like this:
53 +
54 +{{code language="java"}}
55 +
56 +import er.extensions.eof.ERXEC;
57 +import er.extensions.foundation.ERXStringUtilities;
58 +import your.app.model.Author;
59 +
60 + public WOActionResults loginAction() {
61 + WOComponent nextPage = null;
62 + String email = request().stringFormValueForKey("username");
63 + String errorMessage = null;
64 +
65 + try {
66 + Author user = Author.fetchAuthor(ERXEC.newEditingContext(), Author.EMAIL.eq(email));
67 + ((Session) session()).setAuthor(user);
68 + nextPage = ((Session) session()).navController().homeAction();
69 + }
70 + catch (NoSuchElementException e) {
71 + errorMessage = "No user found for that combination of username and password.";
72 + }
73 + catch (Exception e) {
74 + // TODO: handle exception
75 + }
76 + if (!ERXStringUtilities.stringIsNullOrEmpty(errorMessage)) {
77 + nextPage = pageWithName(Main.class);
78 + nextPage.takeValueForKey(errorMessage, "errorMessage");
79 + nextPage.takeValueForKey(email, "username");
80 + }
81 + return nextPage;
82 + }
83 +
84 +{{/code}}
85 +
86 +The **loginAction** logic is quite simple: we check the value from the form, we check in the data source if the email address exists, if that's the case we store it in the session and we redirect the user to the default (//navController().homeAction()//) page, if now the user stays on the Main page.
87 +
88 +We are done with the login logic, so we can move to the next step: working on the navigation. The navigation is quite simple: we want two tabs, //Posts and Authors//, when one of the two tabs is selected, we display the list of objects for the selected tabs, and we have two links: one to create a new blog entry or a new author, and the other to query (search) for matching objects.
89 +
90 +The navigation structure is done in a "plist" file. If you are a Mac OS X guy, you probably know what is a plist, but if not, a plist is like a JSON structure to hold key/values. The plist file is located in the **Resources** folder, the file's name is **NavigationMenu.plist**. By default, Eclipse will open the file in Xcode, which might not be what we want. To open it in a text editor in Eclipse, right-click on **NavigationMenu.plist** and select **Open With** > **Text Editor**.
91 +
92 +[[image:Capture d’écran 2012-07-30 à 06.18.43.png||border="1"]]
93 +
94 +Edit the file with the content is like this:
95 +
96 +{{code}}
97 +
98 +(
99 + {
100 + name = Root;
101 + directActionClass = DirectAction;
102 + directActionName = default;
103 + children = "session.navigationRootChoice";
104 + childrenChoices = {
105 + home = (
106 + Posts,
107 + Authors,
108 + );
109 + };
110 + },
111 + {
112 + name = "Posts";
113 + action = "session.navController.listPostsAction";
114 + children = ("CreatePost","SearchPosts");
115 + },
116 + {
117 + name = CreatePost;
118 + action = "session.navController.createPostAction";
119 + },
120 + {
121 + name = SearchPosts;
122 + action = "session.navController.searchPostsAction";
123 + },
124 + {
125 + name = Authors;
126 + action = "session.navController.listAuthorsAction";
127 + children = ("CreateAuthor","SearchAuthors");
128 + },
129 + {
130 + name = CreateAuthor;
131 + action = "session.navController.createAuthorAction";
132 + },
133 + {
134 + name = SearchAuthors;
135 + action = "session.navController.searchAuthorsAction";
136 + }
137 +)
138 +
139 +{{/code}}
140 +
141 +The first array defines what the top level navigation is going to be, and this is where we define the two tabs (the childrenChoice dictionary). After that, we define the other parts of the navigation. You see references to //action = session.navController//. This is the action (method) that will be called for the specified navigation element, so let's create those methods in the **MainNavigationController** class.