werc Bringing minimalism and sanity to the web

suckless.org werc setup


At http://suckless.org we use a different werc setup. We believe that horizontal menus waste less screen real estate and scale generally better with different screen sizes, particularly on mobile device screens. The default layout requires approx. 16em for the side bar, the horizontal menu approach scales arbitrarily. One drawback with horizontal menus are directories with many entries, which reduces readability. On the other hand this limitation also enforces a carefully chosen structure with usually not more than 10 entries per directory (hence horizontal menu).


In contrast to default werc setups we use 9base instead of plan9port, and discount as markdown filter. We also use nginx as web server together with spawn-fcgi and fcgiwrap, in order to workaround nginx' limitation to only support fcgi (instead of cgi). Please see nginx.conf for further details.

We also modified the following files in order to make our menu approach working and we removed the top_bar.inc inclusion (look at the end to understand why).


    <div id="container">
        <div id="header">
            <div class="midHeader">
    % if(! ~ $#siteImage 0) {
                <h1 class="headerTitle"><a href="/"><img src="%($"siteImage%)" alt="%($"siteTitle%)"/> <span id="headerSubTitle">%($"siteSubTitle%)</span></a></h1>
    % }
    % if not {
                <h1 class="headerTitle"><a href="/">%($"siteTitle%) <span id="headerSubTitle">%($"siteSubTitle%)</span></a></h1>
    % }
             <div id="menu">
    % nav_sites
    % if(! ~ $#handlers_bar_left 0) {
    %   for(h in $handlers_bar_left) {
    %       run_handler $$h 
    %   }   
    % }
        <div id="main-copy">
    % run_handlers $handlers_body_head
    % run_handler $handler_body_main
    % run_handlers $handlers_body_foot
        <div id="footer">
    % cat `{ get_lib_file footer.inc }


    formatter=(fltr_cache markdown)
    sites_menu=(home/:suckless.org code:hg.suckless.org download:dl.suckless.org man/:man.suckless.org dwm/:dwm.suckless.org libs/:libs.suckless.org st:st.suckless.org surf/:surf.suckless.org tools/:tools.suckless.org wmii/:wmii.suckless.org wmi/:wmi.suckless.org)

    fn nav_sites {
            for(m in $sites_menu) {
                    ifs=(':') { co=`{echo -n $m} }
                    if(~ 'http://'^$co(2) $base_url)
                            echo '<li class="thisPage"><a href="http://'^$co(2)^'/">'^$co(1)^'</a></li>'
                                    if not
                                            echo '<li><a href="http://'^$co(2)^'/">'^$co(1)^'</a></li>'

    fn nav_tree {
        if(! ~ $#sideBarNavTitle 0)
            echo '<p class="sideBarTitle">'$"sideBarNavTitle':</p>'
        for(reqp in $req_paths_list) {
            if(~ $style_color $style_color2)
            if not
            ls -F $sitedir/./$reqp >[2]/dev/null \
                | {
                    sed $dirfilter'/\/[^_.\/][^\/]*(\.(md|txt|html)|\/)$/!d; s!^'$sitedir'!!; '$dirclean
                } | sort -u | awk -F/ '
            function p(x, y, s) { for(i=0; i < x-y; i+=1) print s }
            BEGIN { lNF=2; printed=0; style_color=ENVIRON["style_color"]; }
                d = ""
                if(match($0, "/$"))
                    d = "/"
                sub("/$", "") # Strip trailing / for dirs so NF is consistent

                lNF = NF

                bname = $NF d
                path = $0 d
                gsub(/[\-_]/, " ", bname)

                # To avoid false matches add trailing / even for plain files to act as delimiter
                pa = path
                gsub(/[^\/]$/, "&/", pa)

                if(printed == 0) {
                    print "<div id=\"menu\" style=\"background-color: "style_color";\"><ul>";
                if(index(ENVIRON["req_path"] "/", pa) == 1)
                    print "<li class=\"thisPage\"><a href=\"" path "\">" bname "</a></li>"
                    print "<li><a href=\"" path "\">" bname "</a></li>"
            END { if(printed > 0) print "</ul></div>" }'

How it works

In order to generate the horizontal menu we overload werc’s default nav_tree function in etc/initrc.local and as referenced in above lib/default_master.tpl we also introduce a sites_menu list and a new nav_sites function that replaces the original top_bar.inc.

Using the new nav_sites function makes changes to top_bar.inc obsolete and allows us to highlight the active site.

We also introduced siteImage as an additional option for localised _werc/config files. If it is set we display an image instead of a site title for the selected site. See dwm.suckless.org for an example.

Further questions? anselm@garbe.us

To post a comment you need to login first.