Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[doc] book: big blob of changes

  • Loading branch information...
commit 3c855e0175abec0ea5f1dcf89dd48d6c9aecb98e 1 parent 0a61ab3
François-Régis Sinot authored
View
45 doc/book/about.adoc
@@ -7,40 +7,41 @@ myriads of applications. Web applications and technologies available
to developers have evolved tremendously since the first days of the
web.
-Opa is a new generation of web development platform that let you write
-distributed web applications using a single technology. Throughout
-the pages of this book, we will introduce you to all to the many
-features of Opa. To quote but a few, Opa is concise, simple,
+Opa is a new generation of web development platform that lets you
+write distributed web applications using a single technology.
+Throughout the pages of this book, we will introduce you to the
+many features of Opa. To quote but a few, Opa is concise, simple,
concurrent, dynamically distributed, and secure.
What problem does Opa solve?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Unfortunately, the process of web application development has evolved
-neither quite as far nor nearly as fast. Indeed, developing a web
-application in 2011 is not so different from developing a PC
-application in 1991: an impressive amount of developer time is spent
-not working on features or improvements but on _gluing_ together
-antagonist technologies that were never designed to quite work
-together or in this context. In 1991, the technologies were the
-various hardware components, the low-level operating system, the
-high-level operating system and the memory itself, which could only be
-hacked into compliance through copious amounts of machine code. Per
-se, none of these technologies was wrong, but they just failed to fit
-together -- a problem now known as _impedence mismatch_.
+The web is evolving at a very fast pace. Unfortunately, the _process_
+of web application development has evolved neither quite as far, nor
+nearly as fast. Indeed, developing a web application in 2011 is not so
+different from developing a PC application in 1991: an impressive
+amount of developer time is spent not working on features or
+improvements but on _gluing_ together antagonist technologies that
+were never designed to work together or in this context. In 1991, the
+technologies were the various hardware components, the low-level
+operating system, the high-level operating system and the memory
+itself, which could only be hacked into compliance through copious
+amounts of machine code. Per se, none of these technologies was wrong,
+but they just failed to fit together -- a problem now known as
+_impedance mismatch_.
Today, the technologies involved include the various incompatible
browsers, the server components or the database components, to quote
but a few. As in 1991, none of these technologies is wrong, but they
-do not fit together. Because of this impedence mismatch, developers
+do not fit together. Because of this impedance mismatch, developers
need to add to their application logic copious amounts of glue code
just to get the components to agree on communication mechanisms and
application-level protocols. Not only is this glue code tedious,
repetitive and error-prone, but this is also where most safety and
security issues arise.
-In 1991, the answer to impedence mismatch was Software Development
+In 1991, the answer to impedance mismatch was Software Development
Kits, and indeed these SDKs proved very useful at allowing developers
to develop anything at all, but failed to address the underlying
issues. This was only achieved later, through better operating
@@ -49,8 +50,8 @@ Platform, C#, Objective-C or Python, for instance.
In 2011, web frameworks, both client-side and server-side, have the
same role as the SDKs of the 1991s, with the same success but also the
-same shortcomings. But the problem remains: Building applications is
-hackish, relies on glue code and is barely reusable.
+same shortcomings. But the problem remains: Building web applications
+is hackish, relies on glue code and is barely reusable.
How Opa solves it
@@ -67,7 +68,7 @@ Opa is a programming language and a standard library comprising a
database management system, a web server, a server-side framework, a
client-side framework, a distribution middleware, a security audit
tool, but without the complexity of deployment, administration, or
-impedence mismatch stemming from the use of many different
+impedance mismatch stemming from the use of many different
technologies.
Developing with Opa is as simple as it gets: First, write your code
@@ -212,7 +213,7 @@ If you have any question or feedback, do not hesitate to contact us.
A few ways to get in touch:
- Opa https://lists.owasp.org/mailman/listinfo/opa[mailing list];
-- http://stackoverflow.com[Stack Overflow], an excellent site for seeking
+- http://stackoverflow.com/questions/tagged/opa[Stack Overflow], an excellent site for seeking
help with programming problems (do not forget to mark Opa related questions with
the ``Opa'' tag);
- through http://twitter.com/opalang[Twitter], as opalang.
View
2  doc/book/asciidoc.conf
@@ -131,4 +131,4 @@ filter=source-highlight -f {backend-xhtml11?xhtml}{backend-html4?html}{backend-d
\\<\==<=
# Opa
-OPA==Opa
+OPA=Opa
View
228 doc/book/hello_chat/hello_chat.adoc
@@ -1,12 +1,6 @@
Hello, chat
-----------
-//
-// About this chapter:
-// Main author: David
-// Paired author:Norman
-//
-
Real-time web applications are notoriously difficult to develop. They require a
complex and error-prone infrastructure to handle communications between client
and server, and often from server to server, in addition to deep security checks
@@ -32,32 +26,11 @@ start discussing in real-time. On the picture, we have two users, using regular
web browsers. For the sake of simplicity, in this application, we choose the name
of users randomly.
-If you are curious, this is the full source code of the application:
-
-[source, opa]
-------------------------
-include::hello_chat.opa[]
-------------------------
-[run]#http://tutorials.opalang.org/hello_chat[Run]#
-
-In this listing, we define the communication infrastructure for the chatroom,
-the user interface, and finally, the main application. In the rest of the
-chapter, we will walk you through all the concepts and constructions introduced.
-
-A bit of style
-~~~~~~~~~~~~~~
-
-Before exposing the real machinery, let's care from the start how the
-apllication should look like, with this single import line:
-
-[source,opa]
-------------------------
-import stdlib.themes.bootstrap
-------------------------
-
-This automatically brings http://twitter.github.com/bootstrap/[Bootstrap CSS
-from Twitter] to your application, so you can use the predefined classes that
-will just look nice.
+If you are curious, the full source code of the application is listed
+at the end of this chapter. In the rest of the chapter, we will walk
+you through all the concepts and constructions: the communication
+infrastructure for the chatroom, the user interface, and finally, the
+main application.
Setting up communications
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -153,20 +126,28 @@ For starters, consider a possible skeleton for the user interface:
.Skeleton of the user interface (incomplete)
[source,opa]
------------------------
-<div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
-<div id=#conversation class="container"></div>
-<div id=#footer><div class="container">
- <input id=#entry class="xlarge"/>
- <div class="btn primary" >Post</div>
-</div></div>
+<div id=#conversation />
+<input id=#entry />
+<input type="button" value="Post" />
------------------------
-If you are familiar with HTML, you will recognize easily that this skeleton
-defines a few boxes (or +<div>+), with some names (or +id+) and some classes, as
-well as a text input zone (or +<input>+) called +entry+. We will use these names
-to add interactions and style. If you are not familiar with HTML, it might be a
-good idea to grab https://developer.mozilla.org/En/HTML[a good HTML reference]
-and check up the tags as you see them.
+If you are familiar with HTML, you will recognize easily that this
+skeleton defines a few boxes (or +<div>+), with some names (or +id+),
+as well as a text input zone (or +<input>+) called +entry+. We will
+use these names to add interactions and style. If you are not familiar
+with HTML, it might be a good idea to grab
+https://developer.mozilla.org/En/HTML[a good HTML reference] and check
+up the tags as you see them.
+
+[TIP]
+.About HTML
+========================
+There is not much more magic about HTML in Opa than the special
+syntax. For instance, the skeleton that we just defined is a regular
+Opa value, of type +xhtml+. You can for instance inspect its structure
+(with a +match+ construct that we will se later), apply to it
+functions accepting type +xhtml+, or use it as the body of a function.
+========================
Actually, for convenience, and because it fits with the rest of the library, we will
put this user interface inside a function, as follows:
@@ -176,12 +157,9 @@ put this user interface inside a function, as follows:
------------------------
start() =
(
- <div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
- <div id=#conversation class="container"></div>
- <div id=#footer><div class="container">
- <input id=#entry class="xlarge"/>
- <div class="btn primary" >Post</div>
- </div></div>
+ <div id=#conversation />
+ <input id=#entry />
+ <input type="button" value="Post" />
)
------------------------
@@ -228,12 +206,9 @@ At this stage, we can already go a bit further and invent an author name, as fol
start() =
(
author = Random.string(8)
- <div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
- <div id=#conversation class="container"></div>
- <div id=#footer><div class="container">
- <input id=#entry class="xlarge"/>
- <div class="btn primary" >Post</div>
- </div></div>
+ <div id=#conversation />
+ <input id=#entry />
+ <input type="button" value="Post" />
)
------------------------
@@ -285,16 +260,22 @@ that does not fit would be an error.
[TIP]
.About +Dom+
========================
-If you are familiar with web applications, you certainly know about the DOM
-already. Otherwise, it is sufficient to know that DOM, or Document Object Model,
-denotes the manipulation of the contents of a web page once that page is displayed
-in the browser.
+If you are familiar with web applications, you certainly know about
+the DOM already. Otherwise, it is sufficient to know that DOM, or
+Document Object Model, denotes the manipulation of the contents of a
+web page once that page is displayed in the browser. In Opa, elements
+in the DOM have type +dom+. A standard way to access such an element
+is through the selection operator +#+, as in +#entry+ which selects
+the element of id +"entry"+ (ids must be unique in the page). A
+variant of the selection operator is +#{id}+, which selects the DOM
+element whose id is the value of +id+ (so +id+ must be of type
++string+).
=======================
Speaking of types, it is generally a good idea to know the type of
functions. Function +broadcast+ has type +string \-> void+, meaning that it
takes an argument with type +string+ and produces a value with type
-+void+. Also, writing +{author=author text=text}+ is a bit painful, so we added
++void+. Also, writing `{author=author text=text}` is a bit painful, so we added
a syntactic sugar for this. We could have written just as well:
.Broadcasting a message to the room (variant)
@@ -313,25 +294,21 @@ broadcast(author: string): void =
.About +void+
========================
Type +void+ is an alias for the empty record, i.e. the record with no fields.
-It is commonly used for functions whose result is meaningless.
+It is commonly used for functions whose result is uninformative, such as
+functions only producing side-effects or sending messages.
=======================
-This takes care of sending a message to the network. Let us now define the symmetric function
-that we want to be called whenever the network propagates a message:
+This takes care of sending a message to the network. Let us now define
+the symmetric function that should be called whenever the network
+propagates a message:
.Updating the user interface when a message is received
[source,opa]
------------------------
user_update(x: message) =
(
- line = <div class="row line">
- <div class="span1 columns userpic" />
- <div class="span2 columns user">{x.author}:</div>
- <div class="span13 columns message">{x.text}
- </div>
- </div>
- do Dom.transform([ #conversation +<- line ])
- Dom.scroll_to_bottom(#conversation)
+ line = <div>{x.author}: {x.text}</div>
+ Dom.transform([#conversation +<- line ])
)
------------------------
@@ -339,9 +316,7 @@ The role of this function is to display a message just received to the screen.
This function first produces a few items of user interface, using the same
HTML-like syntax as above, and calls these items +line+. It then calls the
+Dom.transform+ function to add the contents of +line+ at the end of box
-+conversation+ we have defined earlier. And finally, it scrolls to the bottom of
-the box, to ensure that the user can always read the most recent items of the
-conversation.
++conversation+ we have defined earlier.
If you look more closely at the HTML-like syntax, you may notice that the contents
inside curly brackets are probably not HTML. Indeed, these curly brackets are
@@ -379,12 +354,9 @@ Let us connect +broadcast+ to our button and our input. This changes function +s
start() =
(
author = Random.string(8)
- <div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
- <div id=#conversation class="container"></div>
- <div id=#footer><div class="container">
- <input id=#entry class="xlarge" onnewline={_ -> broadcast(author)}/>
- <div class="btn primary" onclick={_ -> broadcast(author)}>Post</div>
- </div></div>
+ <div id=#conversation />
+ <input id=#entry onnewline={_ -> broadcast(author)} />
+ <input type="button" onclick={_ -> broadcast(author)} value="Post" />
)
------------------------
@@ -416,28 +388,27 @@ the user loads the page, as follows:
start() =
(
author = Random.string(8)
- <div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
- <div id=#conversation class="container" onready={_ -> Network.add_callback(user_update, room)}></div>
- <div id=#footer><div class="container">
- <input id=#entry class="xlarge" onnewline={_ -> broadcast(author)}/>
- <div class="btn primary" onclick={_ -> broadcast(author)}>Post</div>
- </div></div>
+ <div id=#conversation onready={_ -> Network.add_callback(user_update, room)} />
+ <input id=#entry onnewline={_ -> broadcast(author)} />
+ <input type="button" onclick={_ -> broadcast(author)} value="Post" />
)
------------------------
-This event handler is triggered when the page is (fully) loaded and connects function +user_update+
-to our network.
+This +onready+ event handler is triggered when the page is (fully)
+loaded and connects function +user_update+ to our network.
-And that is it! The user interface is complete and connected to all features. Now, we just need
-to add the +server+ and make things a little nicer.
+And that is it! The user interface is complete and connected to all
+features. Now, we just need to add the +server+ and make things a
+little nicer.
[TIP]
.About +_+
========================
-Opa has a special value name +\_+, pronounced "_I don't care_". It is reserved
-for values or arguments that you are not
-going to use, to avoid clutter. You will frequently see it in event handlers, as it is relatively rare to need
-details on the event, at least in this book.
+Opa has a special value name +\_+, pronounced "_I don't care_". It is
+reserved for values or arguments that you are not going to use, to
+avoid clutter. You will frequently see it in event handlers, as it is
+relatively rare to need details on the event (such as the position of
+the mouse pointer), at least in this book.
=======================
Bundling, building, launching
@@ -543,13 +514,66 @@ Perhaps it is time to add some style.
Adding some style
~~~~~~~~~~~~~~~~~
-In Opa, all styling is done with stylesheets defined in the CSS language. This tutorial is not
-about CSS, so if you feel rusty, it is probably a good idea to keep a
+In Opa, all styling is done with stylesheets defined in the CSS
+language. This tutorial is not about CSS, so if you feel rusty, it is
+probably a good idea to keep a
https://developer.mozilla.org/En/CSS[good reference] at hand.
-You have two possibilities for adding style information. You can either do it
-inside your Opa source file or as an external file. For this example, we will
-use an external file with the following contents:
+Of course, you will always need some custom CSS, specific to your
+application. Still, you can use some standard CSS to get you started
+with some predefined, nice-looking classes. Opa makes this as easy as
+a single import line:
+
+[source,opa]
+------------------------
+import stdlib.themes.bootstrap
+------------------------
+
+This automatically brings
+http://twitter.github.com/bootstrap/[Bootstrap CSS from Twitter] to
+your application, so you can use their predefined classes that will
+just look nice.
+
+A first step is to rewrite some of our simple HTML stubs to give them
+more structure and add classes. The main user interface becomes
+(omitting the event handlers):
+
+.Main user interface
+[source,opa]
+------------------------
+<div class="topbar"><div class="fill"><div class="container"><div id=#logo /></div></div></div>
+<div id=#conversation class="container"></div>
+<div id=#footer><div class="container">
+ <input id=#entry class="xlarge"/>
+ <div class="btn primary" >Post</div>
+</div></div>
+------------------------
+
+And the update function becomes:
+
+.Function to update the user interface when a message is received
+[source,opa]
+------------------------
+user_update(x: message) =
+(
+ line = <div class="row line">
+ <div class="span1 columns userpic" />
+ <div class="span2 columns user">{x.author}:</div>
+ <div class="span13 columns message">{x.text}
+ </div>
+ </div>
+ do Dom.transform([ #conversation +<- line ])
+ Dom.scroll_to_bottom(#conversation)
+)
+------------------------
+
+Note that we have also added a call to +Dom.scroll_to_bottom+, in
+order to scroll to the bottom of the box, to ensure that the user can
+always read the most recent items of the conversation.
+
+For custom style, you have two possibilities. You can either do it
+inside your Opa source file or as an external file. For this example,
+we will use an external file with the following contents:
ifndef::basebackend-docbook[]
.Contents of file +resources/css.css+
@@ -568,7 +592,7 @@ include::resources/css.css[]
endif::basebackend-docbook[]
Create a directory called +resources+ and save this file as +resources/css.css+. It might be a good idea to add a few
-images to the mix, matching the names given in this stylesheet (+opa-logo.png+, +user.png+, +btn_or.png+) also in directory +resources+.
+images to the mix, matching the names given in this stylesheet (+opa-logo.png+, +user.png+) also in directory +resources+.
Now, we will want to instruct our +server+ to access the directory and to use our stylesheet, by rewriting
our +server+ definition as follows:
@@ -808,7 +832,7 @@ equivalently, +match b with \{true\} -> ... | \{false\} -> ...+.
Distinguishing messages between users
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Customize the chat so that your messages are distinguised from messages by other users: your messages should be displayed with one icon and everybody else's messages should be displayed with the default icon.
+Customize the chat so that your messages are distinguished from messages by other users: your messages should be displayed with one icon and everybody else's messages should be displayed with the default icon.
// - Now, expand this beyond two icons. Of course, each user's icon should remain constant during the conversation.
View
9 doc/book/hello_chat/hello_chat.opa
@@ -82,6 +82,9 @@ start() =
* embedding statically the contents of directory "resources", using the global stylesheet
* "resources/css.css" and the user interface defined in [start].
*/
-server = Server.one_page_bundle("Chat",
- [@static_resource_directory("resources")],
- ["resources/css.css"], start)
+// server = Server.one_page_bundle("Chat",
+// [@static_resource_directory("resources")],
+// ["resources/css.css"], start)
+
+
+server = Server.one_page_bundle("Chat", [], [], start)
View
75 doc/book/hello_chat/hello_chat_min.opa
@@ -0,0 +1,75 @@
+/**
+ * Minimal version of hello_chat
+ * - no style
+ * - no @publish
+ */
+
+/**
+ * {1 Network infrastructure}
+ */
+
+/**
+ * The type of messages sent by a client to the chatroom
+ */
+type message = {author: string /**The name of the author (arbitrary string)*/
+ ; text: string /**Content entered by the user*/}
+
+/**
+ * The chatroom.
+ */
+room = Network.cloud("room"): Network.network(message)
+
+/**
+ * {1 User interface}
+ */
+
+/**
+ * Update the user interface in reaction to reception of a message.
+ *
+ * This function is meant to be registered with [room] as a callback.
+ * Its sole role is to display the new message in [#conversation].
+ *
+ * @param x The message received from the chatroom
+ */
+user_update(x: message) =
+ line = <div>{x.author}: {x.text}</div>
+ Dom.transform([#conversation +<- line ])
+
+/**
+ * Broadcast text to the [room].
+ *
+ * Read the contents of [#entry], clear these contents and send the message to [room].
+ *
+ * @param author The name of the author. Will be included in the message broadcasted.
+ */
+broadcast(author) =
+ text = Dom.get_value(#entry)
+ message = {~author ~text}
+ do Network.broadcast(message, room)
+ Dom.clear_value(#entry)
+
+/**
+ * Build the user interface for a client.
+ *
+ * Pick a random author name which will be used throughout the chat.
+ *
+ * @return The user interface, ready to be sent by the server to the client on connection.
+ */
+start() =
+ author = Random.string(8)
+ <div id=#conversation onready={_ -> Network.add_callback(user_update, room)} />
+ <input id=#entry onnewline={_ -> broadcast(author)} />
+ <input type="button" onclick={_ -> broadcast(author)} value="Post" />
+
+/**
+ * {1 Application}
+ */
+
+/**
+ * Main entry point.
+ *
+ * Construct an application called "Chat" (users will see the name in the title bar),
+ * embedding statically the contents of directory "resources", using the global stylesheet
+ * "resources/css.css" and the user interface defined in [start].
+ */
+server = Server.one_page_bundle("Chat", [], [], start)
View
26 doc/book/hello_web_services/hello_web_services.adoc
@@ -1,15 +1,9 @@
Hello, web services
-------------------
-//
-// About this chapter:
-// Main author: David
-// Paired author: Norman
-//
-
Nowadays, numerous web applications offer their features as _web services_, APIs
that can be used by other web applications or native clients. This is how
-Twitter, Github, Google Maps or countless others can be scripted by third-party
+Twitter, GitHub, Google Maps or countless others can be scripted by third-party
applications, using cleanly defined and easily accessible protocols.
With Opa, offering a web service is just as simple as creating any other form of
@@ -34,7 +28,7 @@ Overview
In this chapter, we will modify our wiki to make it accessible by a _REST_
API. This involves few changes from the original wiki, only the addition of a
-few cases to differenciate between several kinds of requests that can be sent by
+few cases to differentiate between several kinds of requests that can be sent by
a client -- which does not need to be a browser anymore.
If you are curious, this is the full source code of the REST wiki server:
@@ -193,25 +187,25 @@ Testing it
~~~~~~~~~~
The simplest way of testing a REST API is to use a command-line tool that lets
-you place requests directly, for instance curl or wget. Assuming
-that curl is installed on your system, the following command-line will test
+you place requests directly, for instance +curl+ or +wget+. Assuming
+that +curl+ is installed on your system, the following command-line will test
the result of placing a +\{get\}+ request at address +\_rest_/hello+:
---------------
curl localhost:8080/_rest_/hello
---------------
-Execute this command-line and curl will show you the result of the call.
+Execute this command-line and +curl+ will show you the result of the call.
Similarly, the following command-line will test the result of placing a +\{post\}+
request at the same address:
---------------
-curl localhost:8080/_rest_/hello -d "I've justed POST to change the contents of my wiki"
+curl localhost:8080/_rest_/hello -d "I've just POSTed to change the contents of my wiki"
---------------
-Now, we are not here to learn about curl, but to learn about Opa. And what best way to test
+Now, we are not here to learn about +curl+, but to learn about Opa. And what best way to test
the REST API of a wiki than by writing a web front-end that does not rely on its own database
but on that of the wiki we have just defined?
@@ -266,7 +260,7 @@ exercises, we decide that any request placed on path +\_rest_+ is a REST request
=========
-For testing, use the following command-line (assuming that curl is installed on your system):
+For testing, use the following command-line (assuming that +curl+ is installed on your system):
--------
@@ -557,7 +551,7 @@ And that is all for the user interface.
Working with URIs
~~~~~~~~~~~~~~~~~
-We have already been using URIs by performing pattern-maching on them inside dispatchers. It is now
+We have already been using URIs by performing pattern-matching on them inside dispatchers. It is now
time to build new URIs for our function +uri_for_topic+.
[TIP]
@@ -938,7 +932,7 @@ This tuple definition defines both +a = 50+ and +b = 51+. You can, of course, us
more complex expressions instead of +50+.
================
-Architecturing a REST chat
+Architecting a REST chat
^^^^^^^^^^^^^^^^^^^^^^^^^^
How would you design a chat distributed among servers using only REST for communications between servers?
View
40 doc/book/hello_wiki/hello_wiki.adoc
@@ -99,7 +99,7 @@ i.e. a simple text in our templating system. As expected, it has type
+Template.default_content+.
With these two lines, the database is set. Any data written to the database will
-be kept persistent, versioned and snapshoted regularly. Should you stop and
+be kept persistent, versioned and with regular snapshots. Should you stop and
restart your application, the data will be checked and made available. If the
data has been corrupted or is somehow incompatible with your application, you
will be informed.
@@ -166,7 +166,7 @@ A value has a _sum type_ +t/u+ if, depending on the execution path, it can
have either values of type +t+ or values of type +u+ . A good example of sum type
is booleans, which are defined as +\{false\}/\{true\}+ . Another good example of
sum type is the type +list+ of linked lists, whose definition can be summed up
-as +\{nil\} / \{\hd: ...; tl: list\}+.
+as +\{nil\} / \{hd: ...; tl: list\}+.
Note that sum types are not limited to two cases. Advanced applications commonly
manipulate sum types with ten cases or more.
@@ -228,7 +228,7 @@ records containing exactly one field called +failure+. When our pattern-matching
encounters such a record, it ignores the contents of the field -- recall that
+_+ is pronounced "I don't care" -- and executes the body.
-Here, we are in the error case, i.e. the user has entered syntactically
+Here, we are in the error case, i.e. the user has entered a syntactically
incorrect text. We could decide to perform sophisticated error reporting, but
that goes beyond the scope of this chapter. We will rather employ an alternative
strategy: we store the text entered by the user, but as source code,
@@ -254,27 +254,29 @@ display(topic) =
<div class="content container">
<div class="page-header"><h1>About {topic}</></>
<div class="well" id=#show_content ondblclick={_ -> edit(topic)}>{load_rendered(topic)}</>
- <textarea clas="xxlarge" rows="30" id=#edit_content onblur={_ -> save(topic)}></>
+ <textarea rows="30" id=#edit_content onblur={_ -> save(topic)}></>
</div>
)
)
-----------------
-This time, instead of producing a +xhtml+ result, we have embed this result in a
-+resource+, i.e. a representation for anything that the server can send to the
-client, whether it is a page, an image, or anything else. In practice, most
-applications produce a set of resources, as this is more powerful and more
-flexible than plain +xhtml+ . Of course, you will need to use the appropriate
-+server+ constructor, which we will introduce later.
-
-A number of functions can be used to construct a +resource+. Here, we use
-+Resource.styled_page+, a function which constructs a web page, from
-its title (first argument), a list of stylesheets (second argument) and +xhtml+
-content. At this stage, the +xhtml+ content should not surprise you. We use
-+<div>+ to display the contents of the page, or
-+<textarea>+ (initially hidden) to modify them. When a user double-clicks on the content of the
-page (event +dblclick+), it triggers function +edit+, and when the user stops
-editing the source (event +blur+), it triggers function +save+.
+This time, instead of producing a +xhtml+ result, we have embedded
+this result in a +resource+, i.e. a representation for anything that
+the server can send to the client, whether it is a page, an image, or
+anything else. In practice, most applications produce a set of
+resources, as this is more powerful and more flexible than plain
++xhtml+. Of course, you will need to use the appropriate +server+
+constructor, which we will introduce later.
+
+A number of functions can be used to construct a +resource+. Here, we
+use +Resource.styled_page+, a function which constructs a web page,
+from its title (first argument), a list of stylesheets (second
+argument) and +xhtml+ content. At this stage, the +xhtml+ content
+should not surprise you. We use +<div>+ to display the contents of the
+page, or +<textarea>+ (initially hidden) to modify them. When a user
+double-clicks on the content of the page (event +dblclick+), it
+triggers function +edit+, and when the user stops editing the source
+(event +blur+), it triggers function +save+.
Function +edit+ is defined as follows:
View
2  doc/book/hello_wiki/hello_wiki.opa
@@ -113,7 +113,7 @@ display(topic) =
<div class="content container">
<div class="page-header"><h1>About {topic}</></>
<div class="well" id=#show_content ondblclick={_ -> edit(topic)}>{load_rendered(topic)}</>
- <textarea clas="xxlarge" rows="30" id=#edit_content onblur={_ -> save(topic)}></>
+ <textarea rows="30" id=#edit_content onblur={_ -> save(topic)}></>
</div>
)
View
45 doc/book/install.adoc
@@ -2,15 +2,15 @@
Getting Opa
-----------
-//
-// About this chapter:
-// Main author: ?
-// Paired author: David
-//
+This section is about installation and configuration of Opa. If you
+want to learn more about Opa first, you can safely skip this section
+and come back later.
-
-At the time of this writing, Opa is available for MacOS X and Linux. A Windows port is in the works and Opa should also work on
-a number of other operating systems (e.g. BSD) but these platforms are not supported for the moment.
+At the time of this writing, Opa is available for MacOS X and Linux
+(both for 64 bits architectures; a 32 bits port is in progress). A
+Windows port is in the works and Opa should also work on a number of
+other operating systems (e.g. BSD) but these platforms are not
+supported for the moment.
Installing Opa
~~~~~~~~~~~~~~
@@ -36,7 +36,7 @@ Ubuntu Linux, Debian Linux
The following instructions are also valid for all Debian-based Linux distributions.
- Download the http://www.opalang.org/get.xmlt[Ubuntu Linux package].
-- Once the download is complete, your operating system will offer you to install Opa using a tool such as gdebi or kdebi.
+- Once the download is complete, your operating system will offer you to install Opa using a tool such as +gdebi+ or +kdebi+.
- Follow the instructions on the screen. You will need the password of an account with administrative rights.
- Once the installation is complete, the Opa compiler will be installed in the directory
@@ -46,6 +46,14 @@ and the documentation and examples will be in
/usr/share/doc/opa
+Arch Linux
+^^^^^^^^^^
+
+A community package is in progress at
+https://aur.archlinux.org/packages.php?ID=51140[AUR]. It is not
+officially supported by us, and we have not tested it, but we are
+interested by any feedback about it.
+
Other Linux distribution
^^^^^^^^^^^^^^^^^^^^^^^^
To install Opa on Suse, Red Hat, Fedora and other distributions of Linux which
@@ -77,11 +85,6 @@ machine, take the following steps:
Building Opa from the sources
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-[CAUTION]
-==========
-Work in progress
-==========
-
Should you wish to work on an unsupported platform, or to contribute to Opa, you will need to build Opa from sources. This requires a bit more work than the
installation, but you should have no major difficulties. You will need:
@@ -105,7 +108,7 @@ In addition, if you are using MacOS X, you will need:
Once these dependencies are satisfied, take the following steps:
-- Grab the sources from http://github.com/MLstate/opalang[github] by entering in a terminal:
+- Grab the sources from http://github.com/MLstate/opalang[GitHub] by entering in a terminal:
------
git clone git@github.com:MLstate/opalang.git
@@ -133,7 +136,6 @@ Emacs
On MacOS-X, either you're using Aquamacs and the package installation took care of it, or you should add the following line to your configuration file (which might be +~/.emacs+).
------
-;; MLstate
(autoload 'opa-mode "/Library/Application Support/Emacs/site-lisp/opa-mode/opa-mode.el" "OPA editing mode." t)
(add-to-list 'auto-mode-alist '("\\.opa$" . opa-mode))
------
@@ -141,14 +143,13 @@ On MacOS-X, either you're using Aquamacs and the package installation took care
On Linux, add the following lines to your configuration file:
------
-;; MLstate
(autoload 'opa-mode "/usr/share/opa/emacs/opa-mode.el" "OPA editing mode." t)
(add-to-list 'auto-mode-alist '("\\.opa$" . opa-mode))
------
[TIP]
==============
-You may want to activate spell-checking on OPA comments and strings. To do so,
+You may want to activate spell-checking on Opa comments and strings. To do so,
type the command +M-x flyspell-prog-mode+ within emacs.
And if you want this functionality activated each time you open an OPA file,
@@ -176,6 +177,14 @@ If you are running Linux (resp. MacOS-X), copy files +/usr/share/opa/vim/{ftdete
Instead of copying you can create a symbolic link. This will let you be automatically up-to-date with the latest mode every time you install a new version of Opa.
==============
+Eclipse
+^^^^^^^
+
+An experimental Eclipse plugin is available from
+https://github.com/MLstate/opa-eclipse-plugin[GitHub]. It is not fully
+functional, but it is good start, and we hope that the open source
+community can help us.
+
Other editors
^^^^^^^^^^^^^
Please sign in to comment.
Something went wrong with that request. Please try again.