-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathstep3.html
More file actions
112 lines (86 loc) · 4.87 KB
/
step3.html
File metadata and controls
112 lines (86 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<html>
<head>
<title>Ur/Web Tutorial</title>
<style>
.code {
background: #d0d0d0;
}
</style>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-10255629-6']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<img src="urheader.png" alt="Ur/Web Tutorial"/></br>
<hr width="99%"/>
<h1>Ur/Web Tutorial</h1>
<h2>Step 3</h2>
<p><a href="step2.html">Previous</a> | <a href="step4.html">Next</a></p>
<p>In the last step we succeeded in querying the database and displaying it. If you didn't go to the trouble of adding some test data to your entry table, you'll want to do this now, because in this step we are going to add a little bit of style.</p>
<p>Adding some data is pretty simple. Ur/Web does some automatic table name generation. Looking inside the <span class="code">urblog</span> database, there is one table: <span class="code">uw_Urblog_entry</span>. Tables are named according to the modules they belong to (and module names are in turn defined by file names -- our <span class="code">entry</span> table is defined inside a file called <span class="code">urblog.ur</span>, which leads to an implied module <span class="code">Urblog</span>). This separation is used by Ur/Web to achieve useful encapsulation of tables, such that one module cannot (inadvertantly or intentionally) interfere with tables that are owned by some other module. I added some test data like this:</p>
<pre class="code">
insert into uw_Urblog_entry (uw_id, uw_title, uw_created, uw_author, uw_body)
values (0, "This is a test entry", now(), "Gian", "This is a test entry. I hope you like it");
insert into uw_Urblog_entry (uw_id, uw_title, uw_created, uw_author, uw_body)
values (1, "This is also a test entry", now(), "Gian", "This is yet another test entry. I hope you like it");
</pre>
<h3>Stylesheets</h3>
<p>Like most of the other commonly-manipulated artifacts of web development, CSS styles are first-class values in Ur/Web, and therefore the compiler can statically ensure that you do not reference undeclared styles. Styles are introduced by the <span class="code">style</span> keyword.</p>
<pre class="code">
style entry
</pre>
<p>In <span class="code">urblog.ur</span>, we're going to include a stylesheet, and define a class for our entry div.<p>
<h3>urblog.ur</h3>
<pre class="code">
[...]
style blogEntry
fun list () =
rows <- queryX (SELECT * FROM entry)
(fn row =>
<xml>
<div class={blogEntry}>
<h1>{[row.Entry.Title]}</h1>
<h2>By {[row.Entry.Author]} at {[row.Entry.Created]}</h2>
<p>{[row.Entry.Body]}</p>
</div>
</xml>
);
return
<xml>
<head>
<title>All Entries</title>
<link rel="stylesheet" type="text/css" href="http://expdev.net/urtutorial/step3/style.css"/>
</head>
<body>
<h1>All Entries</h1>
{rows}
</body>
</xml>
[...]
</pre>
<p>We use a full URL for the style sheet. You are free to replace this with your own stylesheet. Ur/Web enforces certain security constraints on externally-referenced media, so we need to tell Ur/Web that this URL is OK to include, and we specify this in our .urp file.</p>
<h3>urblog.urp</h3>
<pre class="code">
allow url http://expdev.net/urtutorial/step4/style.css
rewrite style Urblog/blogEntry blogEntry
database dbname=urblog
sql urblog.sql
urblog
</pre>
<p>Like all other entities within Ur/Web, styles are named according to their modules. When we defined a style <span class="code">blogEntry</span> in our main source file, that was implicitly tied to the <span class="code">Urblog</span> module, and therefore our generated code would look for a style called <span class="code">Urblog_blogEntry</span> in the <a href="http://github.com/gian/urtutorial/raw/master/step3/style.css">style.css</a> file. This <span class="code">rewrite style</span> syntax allows us to tell Ur/Web what we have really called this style in the CSS file.</p>
<p>We can build and run this exactly as we built the last step:</p>
<pre class="code">
# urweb -dbms mysql -db "password=******* dbname=urblog" urblog
# ./urblog.exe
</pre>
<p>And now you can access the application exactly as you did previously: <a href="http://localhost:8080/Urblog/list">http://localhost:8080/Urblog/list</a>.</p>
<p><a href="step2.html">Previous</a> | <a href="step4.html">Next</a></p>
</body>
</html>