Skip to content

Instantly share code, notes, and snippets.

@DanielSmith
Last active May 14, 2021 22:50
Show Gist options
  • Save DanielSmith/75f15c0be6867dabcafc9e211c99bb2e to your computer and use it in GitHub Desktop.
Save DanielSmith/75f15c0be6867dabcafc9e211c99bb2e to your computer and use it in GitHub Desktop.
gistpad-scratch

ok so this is a gist?

neat

work

import "./style.css";
// our config object - in a dynamic project you would fetch
// JSON from a server, and convert to an object...
import { alapConfig } from "./Config.js";

// our lib, locally...
// import Alap from "../../src/index.js";

// ...or, if you are using npm, this would be:
import Alap from "alap";

// pass the config object
const alap = new Alap(alapConfig);

sdsd

kjadfkj

Overview

Since the dawn of the web, an HTML link is known to lead to one target. What if we could provide more choice?

Alap is a JavaScript package that provides a flexible way to attach menus to links. A JSON object defines an id for each possible link target. Within your HTML, anchors refer to one or more ids. Alap does the work of building up a menus.

You can get it from Github: DanielSmith/alap

Here is a quick idea of the result:


Big Picture of what is possible...

  • link labels and targets are not hardwired in HTML
  • menus are dynamically generated from matched ids and tags
  • custom css can be applied on a per-menu, and, per-item basis
  • simple expressions: can combine ids and tags with AND, OR, and WITHOUT operations
  • menus dismiss themselves with a timeout, or you can click outside them (or hit escape)

Simple Example

The simplest example is for an HTML anchor to refer to a couple of list element ids.

On the HTML side, that looks like:

I like <a id="cars1" class="alap"
  data-alap-linkitems="bmwe36, vwbug">cars</a>,

Alap refers to an object (presumably created from a JSON object from some server call), to find the matches:

bmwe36: {
  label: "BMW (E36) - Wikipedia",
  url: "http://en.wikipedia.org/wiki/BMW_3_Series_(E36)",
  tags: ["e36m3", "bmw", "car", "germany"],
},
vwbug: {
  label: "VW Bug",
  url: "http://en.wikipedia.org/wiki/Volkswagen_Beetle",
  tags: ["vw", "car", "germany"],
}

When we click on "cars", we get a simple menu:

image

So far, we've mentioned two types of IDs:

  • the HTML DOM ID (such as "cars1")
  • the property IDs in a JavaScript object (such as "bmwe36" and "vwbug")

I think of the JavaScript side as "list item IDs"

We could just stop there and have enough to use on a page. Alap is something that potentially transforms writing style - you can write something brisk such as "I can't wait to travel to my favorite cities", and have a menu of 10 cities. You don't have to spell out every last detail in main text.

Using Tags

You probably noticed the tags field in a list item object definition:

vwbug: {
  label: "VW Bug",
  url: "http://en.wikipedia.org/wiki/Volkswagen_Beetle",
  tags: ["vw", "car", "germany"],
}

How are these used?

Let's say we are interested in all of the links we have for a few cities: Sydney, NYC, and London:

<a id="nycsydlon" class="alap"
          data-alap-linkitems=".sydney, .nyc, .london">Sydney, NYC, and London</a>. 

This can be thought of much like CSS Classes: We want to match list items that have a tag of "sydney", "nyc", or "london". Here is very edited chunk of list items that would match:

    brooklynbridge: {
      label: "Brooklyn Bridge",
      url: "http://en.wikipedia.org/wiki/Brooklyn_Bridge",
      tags: ["nyc", "bridge", "brooklyn", "manhattan"],
    },

    manhattanbridge: {
      label: "Manhattan Bridge",
      url: "http://en.wikipedia.org/wiki/Manhattan_Bridge",
      tags: ["nyc", "bridge", "manhattan"],
    },

    sydneyoz: {
      label: "Sydney, Australia",
      url: "http://en.wikipedia.org/wiki/Sydney",
      tags: ["australia", "sydney", "city"],
    },

    sydneybridgeclimb: {
      label: "Sydney Harbour Bridge Tour",
      url: "http://www.bridgeclimb.com",
      tags: ["australia", "sydney", "tour"],
    },

    sydneybotanical: {
      label: "Sydney Botanical Gardens",
      url: "http://www.rbgsyd.nsw.gov.au/",
      tags: ["australia", "sydney", "park"],
    },

    londontowerbridge: {
      label: "London - Tower Bridge",
      url: "http://en.wikipedia.org/wiki/Tower_Bridge",
      tags: ["london", "city", "bridge"],
    },

    londonhyde: {
      label: "London - Hyde Park",
      url: "http://www.royalparks.gov.uk/Hyde-Park.aspx",
      tags: ["london", "city", "park"],
    },

From that, we might get a menu such as:

image

Custom CSS

There are two CSS areas that are easy to customize with alap:

  • the menu itself
  • an individual list item

the alapelem div

The container for the alap menu is a div with the id of alapelem

It also sets a class named alapelem

It also picks up a class that is named from the anchor that was clicked. Example:

<!-- here is our anchor -->
<a id="cars1" class="alap" data-alap-linkitems="bmwe36, vwbug">cars</a>

<!-- the anchor id of "cars1" gives us a class of "alap_cars1" -->
<div id="alapelem" class="alapelem alap_cars1"><ul>

This means that in our CSS Styles, we could do something special for a specific menu:

.alap_cars1 {
  /* change the font, colors, etc... */
}

Per-Item override

We can also target CSS for an individual list item. This is done by using the cssClass property in a list item definition:

kittyatola_yt: {
  label: "Kitty - Atola Visuals (YouTube)",
  url: "https://www.youtube.com/c/atolavisuals/videos",
  cssClass: "violetclass",
  tags: [
    "atolavisuals",
    "lapeople",
    "cinematography",
    "video",
    "photography",
    "techreview",
    "youtube",
  ],
},

In turn, that particular list item generates an extra class (besides alapListElem):

class="alapListElem violetclass"

which will match a CSS Style Rule:

.violetclass {
  background-color: violet;
}

Giving a result where we can style per-item

image

Overall Config File, And Settings

Before diving into settings, let's see the overall structure of the Config file:

  • settings
  • macros
  • allLinks
export const alapConfig = {
  settings: {
    listType: "ul",
    menuTimeout: 5000,
  },

  macros: {
    cars1: {
      linkItems: "vwbug, bmwe36",
      config: {
        somekey: "somevalue",
      },
    },
  },

  allLinks: {
    vwbug: {
      label: "VW Bug",
      url: "http://en.wikipedia.org/wiki/Volkswagen_Beetle",
      tags: ["vw", "car", "germany"],
    }
  }
};

Global Settings

As you can see, we have two possible settings at the global level:

  • listType - ol or ul for ordered, or unordered list
  • menuTimeout - time in ms, before menu dismisses itself (if you mouse away)

Macros

Throughout this article, We have been referring to list item definitions within the allLinks object. The other main item in the Config is macros.

Here is a sample:

cars1: {
  linkItems: "vwbug, bmwe36",
  config: {
    somekey: "somevalue",
  }
}

For the moment, the config section within a macro is not being used.

A macro is referred to in an anchor definition via the @ character. Example:

 <a id="cars1" class="alap" data-alap-linkitems="@cars1">cars</a>

What is the benefit of using a macro?

A macro lets you say "in my HTML, don't hardwire specifics about the menu I want. Go look it in up in the Config. Grab it from the linkItems field there".

As a convenience, if you just specify "@", the macro will get its name from the id of the anchor tag. Example: id="germanbeer" data-alap-linkitems="@" would be like specifying the macro as "@germanbeer"

Simple Expressions

Simple expressions let us do AND, OR, and WITHOUT operations.

operator description example meaning
+ AND .nyc + .bridge items tagged with nyc AND bridge
| OR .nyc | .bridge items tagged with nyc OR bridge
- WITHOUT .nyc - .bridge items tagged with nyc, WITHOUT a tag of bridge

Note: using | for OR is much like a list of comma separated items (nyc, bridge). I include the | operator to be more complete in what one would expect from expressions.

Expressions can be built up. You can say something like "Show me the links for all of the bridges you know of, but toss out the ones from NYC and London":

.bridges - .nyc - .london

Summing Up For Now

This gives a brief look at what alap does. It's a means of attaching menus to links. Since we use a JSON object to define our labels, link targets, tags, and more, we gain a lot of runtime flexibility. Anchors become a placeholder that express "this is what I want", and alap builds a menu based on the data available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment