Skip to content

Commit

Permalink
New version of tutochat
Browse files Browse the repository at this point in the history
  • Loading branch information
balat committed Sep 16, 2024
1 parent fd38c87 commit 3ff4734
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 102 deletions.
111 changes: 87 additions & 24 deletions talks/tutochat.html
Original file line number Diff line number Diff line change
Expand Up @@ -1780,12 +1780,15 @@
<slip-slipshow>
<slip-slip immediate-enter>
<slip-body>
<style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap" rel="stylesheet">
<style>
slip-slipshow>slip-slip>.slip-scale-container>.slip-container>slip-body {
margin: 0 auto;
}
slip-body {
font-family: "Ubuntu";
font-family: "Ubuntu", sans-serif;
line-height: 1.4;
margin: 0;
color: #555;
Expand Down Expand Up @@ -1813,6 +1816,7 @@
.vspace { height: 1em; }
.hidden { position:absolute; visibility: hidden; }
.center { text-align: center; }
.right { text-align: right; }
.smaller { font-size: smaller; }
.focused { outline: 20000px solid #000000aa; }
.comment { color: #888; font-style: italic; }
Expand Down Expand Up @@ -1857,7 +1861,7 @@
pre.tt code { padding-top: 0; }
.hljs-deletion, .hljs-number, .hljs-quote, .hljs-selector-class, .hljs-selector-id, .hljs-template-tag, .hljs-type { color: #2788f1; }
.hljs-string { color: #e88; }
#scopes:before {
#scopes::before {
content: '⬉';
position: absolute;
top: -90px;
Expand All @@ -1866,6 +1870,18 @@
font-size: 100px;
color: #ee5522;
}
#servparam .encadré { position: fixed; bottom: 1550px; left: 400px; width: 600px;}
#servparam .encadré::after { content: '⬇'; position: absolute; bottom: -120px; left: 300px; font-weight: bold; font-size: 100px; color: #ee5522;}
#regparam .encadré { position: fixed; bottom: 1250px; left: 200px; width: 600px;}
#regparam .encadré::after { content: '⬇'; position: absolute; bottom: -120px; left: 100px; font-weight: bold; font-size: 100px; color: #ee5522;}
#regparam2 .encadré { position: fixed; bottom: 1200px; left: 200px; width: 600px;}
#regparam2 .encadré::after { content: '⬇'; position: absolute; bottom: -120px; left: 230px; font-weight: bold; font-size: 100px; color: #ee5522;}
#regparam3 .encadré { position: fixed; bottom: 1250px; left: 200px; width: 600px;}
#regparam3 .encadré::after { content: '⬇'; position: absolute; bottom: -120px; left: 230px; font-weight: bold; font-size: 100px; color: #ee5522;}
#regparam4 .encadré { position: fixed; bottom: 1250px; left: 200px; width: 600px;}
#regparam4 .encadré::after { content: '⬇'; position: absolute; bottom: -140px; left: 300px; font-weight: bold; font-size: 100px; color: #ee5522;}
#regparam5 .encadré { position: fixed; bottom: 1680px; left: 650px; width: 600px;}
#regparam5 .encadré::after { content: '⬇'; position: absolute; bottom: -80px; left: 150px; font-weight: bold; font-size: 100px; color: #ee5522;}
</style>
<div id="title" class="columns">
<div class="col" style="flex: 0 0;">
Expand All @@ -1880,7 +1896,11 @@ <h1 id="ocsigen-quickstart-guide"><a class="anchor" aria-hidden="true" href="#oc
<p><span>FUN-OCaml - Berlin</span><br/><span> Sep 16-17 2024</span></p>
</div>
</div>
<div style="height: 400px; width:100%;"></div>
<div class="vspace"></div>
<div class="vspace"></div>
<p class="right comment"><span>Use arrow keys to navigate</span></p>
</slip-body>
</slip-slip>
<div class="slip-group">
<slip-slip style="width: 33.33%;" auto-enter scale="0.3333" delay="1">
<slip-body>
Expand All @@ -1894,6 +1914,8 @@ <h2 id="install"><a class="anchor" aria-hidden="true" href="#install"></a><span
<p class="comment"><span>You can find these slides on </span><a href="https://ocsigen.org/talks/tutochat.html"><span>ocsigen.org</span></a><span> </span><br>
<span>and the source code of the sides with the solution of</span>
<span>exercices </span><a href="https://github.com/ocsigen/quickstart-guide"><span>on Github</span></a><span>.</span></p>
<p class="comment"><span>Refer to the main </span><a href="https://ocsigen.org/tuto/latest/manual/basics" target="_blank"><span>one page user manual</span></a>
<span>to get more explanations.</span></p>
</slip-body>
</slip-slip>
<slip-slip style="width: 33.33%;" auto-enter scale="0.3333" delay="1">
Expand All @@ -1903,7 +1925,7 @@ <h2 id="install"><a class="anchor" aria-hidden="true" href="#install"></a><span
<p><img alt="Ocsigen" src="be-ocsigenlogo.svg" width="200px"/><br/>
<img alt="Ocsigen" src="ocsigen-bubbles-large.png" width="800px"/></p>
</div>
<p style="position: absolute; top: 100px; left: 960px;"><span>Ocsigen Server</span></p>
<p style="position: absolute; top: 100px; left: 940px;"><span>Ocsigen Server</span></p>
<p id="aaa" style="position: absolute; top: 320px; left: 1000px;"><span>Eliom</span></p>
<p style="position: absolute; top: 520px; left: 940px;"><span>Js_of_ocaml</span></p>
<p style="position: absolute; top: 700px; left: 800px;"><span>Tyxml</span></p>
Expand Down Expand Up @@ -2008,12 +2030,18 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="
~meth:(Eliom_service.Get Eliom_parameter.unit)
()
</code></pre>
<pre id="servparam" class="server hidden"><code class="language-ocaml">let myservice =
<div id="servparam" class="server hidden">
<pre><code class="language-ocaml">let myservice =
Eliom_service.create
~path:(Eliom_service.Path [&quot;foo&quot;])
~meth:(Eliom_service.Get (Eliom_parameter.(string &quot;myparam&quot; ** int &quot;i&quot;)))
()
</code></pre>
<div id="servparamexpl" class="encadré">
<p><span>Use module </span><code>Eliom_parameter</code><span> to specify which GET or POST parameters you want your page to take.</span></p>
<p><span>Eliom checks types automatically and converts them to OCaml values</span></p>
</div>
</div>
<p><span>Register a handler:</span></p>
<pre id="regunit" class="server"><code class="language-ocaml">let () =
Eliom_registration.Html.register ~service:myservice
Expand All @@ -2022,33 +2050,59 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="
Eliom_content.Html.F.(html (head (title (txt &quot;The title&quot;)) [])
(body [h1 [txt &quot;Hello&quot;]])))
</code></pre>
<pre id="regparam" class="server hidden"><code class="language-ocaml">let () =
<div id="regparam" class="server hidden">
<pre><code class="language-ocaml">let () =
Eliom_registration.Html.register ~service:myservice
(fun (myparam, _i) () -&gt;
Lwt.return
Eliom_content.Html.F.(html (head (title (txt &quot;The title&quot;)) [])
(body [h1 [txt myparam]])))
</code></pre>
<pre id="regparam2" class="server hidden"><code class="language-ocaml">let () =
<div id="regparamexpl" class="encadré">
<p><span>The service handler now takes as first argument something of type </span><code>string * int</code></p>
</div>
</div>
<div id="regparam2" class="server hidden">
<pre><code class="language-ocaml">let () =
Eliom_registration.File.register ~service:myservice
(fun (_myparam, _i) () -&gt;
Lwt.return &quot;filename&quot;)
</code></pre>
<pre id="regparam3" class="server hidden"><code class="language-ocaml">let () =
<div class="encadré">
<p><span>Services can return other types of content.</span></p>
<p><span>For example, we can return a file:</span></p>
</div>
</div>
<div id="regparam3" class="server hidden">
<pre><code class="language-ocaml">let () =
let a = ref 0 in
Eliom_registration.Action.register ~service:myservice
(fun (myparam, _i) () -&gt;
a := a + 1;
Lwt.return ())
</code></pre>
<pre id="regparam4" class="server hidden"><code class="language-ocaml">let () =
<div class="encadré">
<p><span>or an </span><em><span>action</span></em><span>.</span></p>
<p><span>Actions are services performing a side-effect.</span>
<span>Handlers do not return any value.</span>
<span>By default, the current page is regenerated.</span></p>
</div>
</div>
<div id="regparam4" class="server hidden">
<pre><code class="language-ocaml">let () =
Eliom_registration.Html.register ~service:myservice
(fun (myparam, _i) () -&gt;
Lwt.return ([%html{|&lt;html&gt;&lt;head&gt;&lt;title&gt;&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;&lt;h1&gt;Hello&lt;/h1&gt;&lt;/body&gt;
&lt;body&gt;&lt;h1&gt;Hello&lt;/h1&gt;&lt;/body&gt;
&lt;/html&gt;|})
</code></pre>
<pre id="regparam5" class="server hidden"><code class="language-ocaml">let () =
<div class="encadré">
<p><span>A PPX extension provided by Tyxml makes it possible to use</span>
<span>regular HTML syntax if you prefer</span></p>
</div>
</div>
<div id="regparam5" class="server hidden">
<pre><code class="language-ocaml">let () =
Eliom_registration.Html.register ~service:myservice
(fun (myparam, _i) () -&gt;
Lwt.return
Expand All @@ -2058,7 +2112,7 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="
Error: This expression has type [&gt; p ] elt = 'a elt
but an expression was expected of type [&lt; p_content ] elt = 'b elt

Type 'a = [&gt; `P ] is not compatible with type
Type 'a = [&gt; `P ] is not compatible with type
'b = [&lt; `A of phrasing_without_interactive
| `Abbr
| `Audio of phrasing_without_media
Expand All @@ -2072,6 +2126,11 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="

The second variant type does not allow tag(s) `P
</code></pre>
<div class="encadré">
<p><span>Tyxml type-checks your HTML!</span>
<span>This makes sure at compile time your program will never generate incorrect pages!</span></p>
</div>
</div>
<div id="tyxmlend" down-at-unpause=sdkjf pause></div>
<p><span>Start the server with static files and Eliom:</span></p>
<pre class="server"><code class="language-ocaml">let () =
Expand All @@ -2097,7 +2156,7 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="
<script type=slip-script exec-at-unpause static-at-unpause="servparam" unstatic-at-unpause="servunit" pause>
document.querySelector("#servunit").classList.remove("focused")
document.querySelector("#servparam").classList.add("focused")</script>
<script type=slip-script exec-at-unpause focus-at-unpause=regunit pause>
<script type=slip-script exec-at-unpause focus-at-unpause=regunit unstatic-at-unpause="servparamexpl" pause>
document.querySelector("#servparam").classList.remove("focused")
document.querySelector("#regunit").classList.add("focused")</script>
<script type=slip-script exec-at-unpause focus-at-unpause=regparam static-at-unpause="regparam" unstatic-at-unpause="regunit" pause>
Expand All @@ -2109,7 +2168,7 @@ <h2 id="generating-pages-with-eliom"><a class="anchor" aria-hidden="true" href="
<script type=slip-script exec-at-unpause focus-at-unpause=regparam3 static-at-unpause="regparam3" unstatic-at-unpause="regparam2" pause>
document.querySelector("#regparam2").classList.remove("focused")
document.querySelector("#regparam3").classList.add("focused")</script>
<script type=slip-script exec-at-unpause focus-at-unpause=regparam static-at-unpause="regparam" unstatic-at-unpause="regparam3" pause>
<script type=slip-script exec-at-unpause focus-at-unpause=regparam static-at-unpause="regparam" unstatic-at-unpause="regparam3 regparamexpl" pause>
document.querySelector("#regparam3").classList.remove("focused")
document.querySelector("#regparam").classList.add("focused")</script>
<script type=slip-script exec-at-unpause focus-at-unpause=regparam4 static-at-unpause="regparam4" unstatic-at-unpause="regparam" pause>
Expand Down Expand Up @@ -2194,14 +2253,13 @@ <h2 id="implement-a-basic-login-mechanism"><a class="anchor" aria-hidden="true"
<div pause></div>
<p><span>Hints:</span></p>
<ul>
<li><span>See an example of form </span><a target="_blank" href="https://ocsigen.org/tuto/dev/manual/basics-server#h5o-25"><span>here</span></a></li>
<li><span>See an example of POST service </span><a target="_blank" href=""><span>here</span></a></li>
<li><span>See an example of form and POST service </span><a target="_blank" href="https://ocsigen.org/tuto/dev/manual/basics-server#h5o-25"><span>here</span></a></li>
<li><span>Use an </span><strong><span>action</span></strong><span> (service with no output, that will just redisplay the page after perfoming a side-effect) to set a scoped reference with the user name</span></li>
<li><span>To close the session use function </span><a target="_blank" href=""><code>Eliom_state.discard_all</code></a></li>
<li><span>To close the session use function </span><a target="_blank" href="https://ocsigen.org/eliom/latest/api/server/Eliom_state#VALdiscard_all"><code>Eliom_state.discard_all</code></a></li>
</ul>
<p><span>Test your app with several browsers to check that you can have several users simultaneously.</span></p>
<div down-at-unpause=endstep4 pause></div>
<p class="comment"><span>See the solution </span><a href="https://github.com/ocsigen/quickstart-guide/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
<p class="comment"><span>See the solution </span><a target="_blank" href="https://github.com/ocsigen/quickstart-guide/blob/Step4/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
<p class="exo"><span>Advanced version: instead of using a reference with scope session,</span>
<span>create a session group whose name is the user name.</span>
<span>Check that you can share session data across multiple browsers.</span></p>
Expand Down Expand Up @@ -2334,6 +2392,9 @@ <h3 id="client-values-inserting-client-side-code-in-your-pages"><a class="anchor
<slip-slip style="width: 33.33%;" auto-enter scale="0.3333" delay="1">
<slip-body>
<h2 id="client-side-services"><a class="anchor" aria-hidden="true" href="#client-side-services"></a><span>Client-side services</span></h2>
<p><strong><span>Generating pages on the client or the server depending on cases</span></strong></p>
<p><span>This is a typical example of service definition and registration</span>
<span>for a client-server Web and mobile app:</span></p>
<pre class="b server"><code class="language-ocaml">let%server myservice = Eliom_service.create
~path:(Path [&quot;foo&quot;])
~meth:(Get any)
Expand Down Expand Up @@ -2371,7 +2432,7 @@ <h2 id="client-server-version-of-your-program"><a class="anchor" aria-hidden="tr
<span>that is, when a page is generated on the server (subsequent pages are generated</span>
<span>on the client, without stopping the client-side process).</span></li>
</ol>
<p class="comment"><span>See the solution </span><a href="https://github.com/ocsigen/quickstart-guide/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
<p class="comment"><span>See the solution </span><a target="_blank" href="https://github.com/ocsigen/quickstart-guide/blob/Step5/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
</slip-body>
</slip-slip>
<slip-slip style="width: 33.33%;" auto-enter scale="0.3333" delay="1">
Expand Down Expand Up @@ -2436,10 +2497,12 @@ <h2 id="send-a-message-to-another-user"><a class="anchor" aria-hidden="true" hre
<p><span>Make sure that you receive only the message sent to you.</span></p>
<p><span>Hints:</span></p>
<ol>
<li><span>Use module </span><a href="https://ocsigen.org/eliom/api/11.0/Eliom_content.Html.Manip"><code>Manip</code></a><span> to append the new element to the page</span></li>
<li><span>To_dom.of_element</span></li>
<li><span>Instantiate functor </span><code>Eliom_notif.Make_Simple</code><span> on server side, with </span><code>get_identity</code><span> being the function to get current user from your scoped reference. Resources are chat channels. Here a channel is identified (</span><code>key</code><span>) by the recipient name (one channel for each user, where everyone can write).</span></li>
<li><span>Your RPC to send a message will now notify the recipient (server-side)</span></li>
<li><span>Every time the client process starts (i.e. every time a page is generated on the server), you need to start listening on your own channel (on server-side), and ask the client to react to event </span><code>client_ev</code></li>
<li><span>Use module </span><a href="https://ocsigen.org/eliom/latest/api/client/Eliom_content.Html.Manip"><code>Manip</code></a><span> to append the new element to the page</span></li>
</ol>
<p class="comment"><span>See the solution </span><a href="https://github.com/ocsigen/quickstart-guide/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
<p class="comment"><span>See the solution </span><a target="_blank" href="https://github.com/ocsigen/quickstart-guide/blob/Step7/myapp/myapp.eliom"><span>here</span></a><span>.</span></p>
</slip-body>
</slip-slip>
</div>
Expand Down Expand Up @@ -2497,7 +2560,7 @@ <h2 id="mobile-apps"><a class="anchor" aria-hidden="true" href="#mobile-apps"></
<slip-body>
<h2 id="how-to-learn-more"><a class="anchor" aria-hidden="true" href="#how-to-learn-more"></a><span>How to learn more?</span></h2>
<p><span>Please read the</span>
<a href="https://ocsigen.org/tuto/basics" target="_blank"><span>main tutorial</span></a><span> first!</span></p>
<a href="https://ocsigen.org/tuto/latest/manual/basics" target="_blank"><span>main documentation page</span></a><span> first!</span></p>
<p><span>and look at each example in Ocsigen Start's template.</span></p>
<p style="text-align: right;"><img alt="Ocsigen" src="ocsigen-bubbles-large.png" width="800px"/><br/>
<span style="color: #aaa"><span>Slides powered by </span><a href="https://github.com/panglesd/slipshow"><span>Slipshow</span></a></span><span>.</span></p>
Expand Down
Loading

0 comments on commit 3ff4734

Please sign in to comment.