From 963ab32b176228017635e4ef1bb60555c4022142 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 16 Mar 2013 16:08:06 -0400 Subject: Give up on typesafe menu generation and use 'bless' --- menu.ur | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 menu.ur (limited to 'menu.ur') diff --git a/menu.ur b/menu.ur new file mode 100644 index 0000000..4be6d3d --- /dev/null +++ b/menu.ur @@ -0,0 +1,57 @@ +(* Menu -- site menu +Copyright (C) 2013 Benjamin Barenblat + +This file is a part of 6.947. + +6.947 is is free software: you can redistribute it and/or modify it under the +terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +6.947 is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU Affero General Public License for more +details. + +You should have received a copy of the GNU Affero General Public License along +with 6.947. If not, see . *) + +(* Generating nice headings and menus is quite difficult in Ur/Web--there are a +lot of links that the compiler needs to be convinced aren't broken. I tried +for multiple weeks to get a nice, typesafe solution to this; however, it was +just too brittle. I've instead settled for a simpler solution--pass the URLs +of the pages the menu links to to 'bless'. It's a bit sketchy, but it works, +and it's no more unsafe than anything you'd do in a "normal" Web framework. *) + +open Styles + +con pageName = variant (mapU unit [Main, Forum]) + +(* Generates the link text *) +fun getName (n : pageName) : xbody = + match n { Main = fn () => Main, + Forum = fn () => Forum } + +(* Generates the link URL *) +fun getUrl (n : pageName) : url = + let val base = "/urweb/6.947" + in + match n { Main = fn () => bless (base ^ "/index"), + Forum = fn () => bless (base ^ "/forum") } + end + +(* Actual title and menu generation code *) +fun header (current : pageName) : xbody = + let fun item (target : pageName) = + if Variant.eq current target + then
  • {getName target}
  • + else
  • {getName target}
  • + in + +

    6.947 – Functional Programming Project Laboratory

    +
      + {item (make [#Main] ())} + {item (make [#Forum] ())} +
    +
    + end -- cgit v1.2.3