-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathstep1.html
More file actions
111 lines (83 loc) · 4.94 KB
/
step1.html
File metadata and controls
111 lines (83 loc) · 4.94 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
111
<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 1</h2>
<p><a href="index.html">Previous</a> | <a href="step2.html">Next</a></p>
<p>We're going to create a directory <span class="code">urblog</span> for our project, and in it we will create three (empty) files:
<pre class="code">
urblog/
urblog.urp
urblog.urs
urblog.ur
</pre>
Now, to add some content to these files!</p>
<h3>urblog.urp</h3>
<p>
A <span class="code">.urp</span> file describes the files to be included within our project. In this case, we just want to ensure that our main source file <span class="code">urblog.ur</span> and its signature definition file <span class="code">urblog.urs</span> are included:
<pre class="code">
urblog
</pre>
No file extensions are necesary here -- the use of a filename prefix such as this one causes the inclusion of the appropriate .ur and .urs files.</p>
<h3>urblog.urs</h3>
<p>
A <span class="code">.urs</span> file is a <em>signature definition</em> that describes what artifacts of our implementation will be visible to the outside world:
<pre class="code">
val main : unit -> transaction page
</pre>
We start by defining only a single function <span class="code">main</span> that will be visible. It takes as input values of type <span class="code">unit</span> and returns a value of type <span class="code">transaction page</span>. We'll describe what exactly that means a little later.</p>
<h3>urblog.ur</h3>
<p>
The <span class="code">.ur</span> file holds actual implementation code. According to the signature we provided in <span class="code">urblog.urs</span>, we are obligated to provide a function called <span class="code">main</span>, so let's go ahead and do that:
<pre class="code">
fun main () = return <xml>
<head>
<title>UrBlog</title>
</head>
<body>
<h1>UrBlog</h1>
</body>
</xml>
</pre>
If you're used to working in a programming language that treats HTML and XML as strings, then this might look a little surprising. Within Ur/Web, XML fragments such as these are first-class values (in exactly the same way as integers, strings or booleans might be). The use of <span class="code">return</span> takes us back to the use of the type <span class="code">transaction page</span> earlier. The XML fragment has the type <span class="code">page</span>, and <span class="code">return</span> makes this expression part of a transaction, which is a monad in the style of the Haskell IO monad.
</p>
<h2>Putting it all together</h2>
<p>OK, so we've got our source files. You can compile it all by running:
<pre class="code">
urweb urblog
</pre>
from inside the urblog directory. This should result in a binary called <span class="code">urblog.exe</span>.</p>
<p>If your system is anything like mine, you can run this binary using a command like <span>./urblog.exe</span>, which results in output such as:
<pre class="code">
urblog # ./urblog.exe
Database connection initialized.
Listening on port 8080....
Database connection initialized.
Database connection initialized.
</pre>
Marvelous! The stand-alone webserver associated with your application is now listening for connections on port 8080. The exact URL is munged slightly by Ur/Web, such that your module name with the first letter upper-cased is the first URI component, followed by the name of any function that is visible outside the module (i.e. roughtly any appropriately-typed functions that are included in the <span class="code">urblog.urs</span> file, or any appropriate-typed functions that these depend upon). Putting it all together, we can access our application's main function at this URL:</p>
<p><a href="http://localhost:8080/Urblog/main">http://localhost:8080/Urblog/main</a></p>
<p>(Note: This is a localhost URL. You must have the server running on your local machine, and have appropriate firewall/connection settings to permit you to make a connection to your local machine on port 8080).</p>
<p>If all of that worked, you should see a not-particularly-exciting web application featuring the word 'UrBlog' on a blank page. If it didn't work, you might have done something wrong, or there could be something wrong with your configuration. Now might be a good time to join the #ur IRC channel on Freenode.</p>
<p><a href="index.html">Previous</a> | <a href="step2.html">Next</a></p>
</body>
</html>