From IndieWeb
Jump to: navigation, search

Falcon is a personal publishing (tweeting, blogging, realtime syndicating) web application, some of it available as open source. There is an instance of Falcon running at tantek.com and serving/syndicating notes, articles, and several other types of posts.



Note: documentation purely for informational purposes.

Though many aspects of this design are suboptimal, Falcon has been running continuously since 2010-01-01 (on tantek.com), in nearly daily use for publishing, iterated live, and thus perhaps some of it may help with designing or improving your own practical indieweb implementation.

In addition, feel free to use and improve on the brainstorming of items I am #Working_On or #Itches to scratch.

If something doesn't make sense, ask, e.g. in IRC, as there's a good chance it's something that I should fix in the design.


Open Source

Open source portions of Falcon:


Falcon supports:

Home Page Features

The following sections are generated by Falcon and inserted into the index.html homepage template:

Posts In General

All posts support the following features:

  • permalinks, permashortlinks, permashortcitations
  • h-entry + author h-card
  • custom post style (all posts except "like" posts) - which is rendered on the post permalink page, and as a post-scoped style sheet on both the homepage stream and any archive pages that contain the post, styling only the post itself on those pages.
    • The custom post style must have style rules with at least the ".h-entry" selector in order to take effect on that post in when it's present in any context.

Note: auto-linking and auto-embedding for all types that support them is all accomplished with the open source CASSIS auto_link function.

Falcon supports the following specific kinds of posts.


note posts are supported with:

  • white-space (serial space characters, line-breaks, blank lines)
  • auto-linking of URLs, @-names to Twitter
  • auto-embedding of JPG/PNG/GIF/MP4/MOV/OGV and YouTube/Vimeo URLs
  • POSSE to Twitter of up to 118 chars with permashortid of original post, or first 110-113 chars with ellipsing/truncating and permashortlink to original post. (assuming 6 char personal short domain, e.g. ttk.me)
  • webactions: like, repost, reply with Twitter fallbacks


articles as blog posts are supported with:

  • POSSE to Twitter of up to 113 chars long article name with permashortlink of full post, or first 110-113 chars with ellipsing/truncating and permashortlink to original post. (assuming 6 char personal short domain, e.g. ttk.me)
  • webactions: Post with Twitter Tweet fallback.
  • citation UI for copy pasting URL or HTML embed with h-cite markup.


reply notes are supported. Replies are similar to notes, but for replying to tweets, commenting on other posts.

  • with minimal reply-context support (linked URL of original being replied to)
  • with multi-reply reply-context presentation support too.
  • automatic sending of webmentions (or pingbacks if no webmention endpoint) to original post (since 2015-163)
  • reply to tweet permalink posts a POSSE @-reply threaded to the tweet permalink
  • reply to GitHub issue posts a POSSE reply on that GitHub issue (since 2018-050)
  • current reply limitations:
    • replies directly to tweets (Tweet permalink URLs) are well supported. This enables POSSEing @-replies to Twitter and have them thread properly on Twitter, which helps interact with friends who use Twitter instead of their own site (most people).
    • replies to indieweb URLs are supported for posting / storing / presenting, but won't auto-thread to their POSSE copies.
    • multi-reply support provides a manual work-around for replying to an indieweb URL and also replying to the POSSE copy of that indieweb URL (and thus threading with it on Twitter). This provides the ability to post a reply to an indieweb post that is also a reply to its POSSE tweet, and thus POSSE @-reply to thread properly to the original POSSE tweet.
    • replies to GitHub issues are deliberately not POSSEd to Twitter
    • Pending: There's two itches below for supporting replies either to POSSE tweets or original posts, automatically discovering the other if present, preferring the original post in reply-context presentation, and threading with the POSSE tweet if any.


likes are supported, and sequential likes are collapsed for presentational purposes on the main home stream.


rsvp notes are supported. RSVP posts are similar to reply notes, but for RSVPing to indieweb event posts. (since 2013-264, full RSVP values support since 2017-016!)

  • p-rsvp marked up with a element in its reply-context where it says e.g. "RSVP something to", where something is yes, no, maybe, or interested. E.g. 2013-264 RSVP.
  • only works for indieweb event posts. no explicit POSSE reply threading support, though multireply RSVP posts are supported for combined RSVPing to an indie event and silo POSSE copy.
  • Supports all RSVP values! yes, maybe, no, interested
    • "yes" via text starting with: "going to " (since first implementation) or "went to " (since 2016-336)
    • "maybe" via text starting with: "might go to " (since 2017-016) or "might remotely attend " (since 2015-042)
    • "no" via text starting with: "not going to " (since 2015-043) or "missing "
    • "interested" via text starting with: "considering today", "considering tonight", "considering going to "
  • webmention(s) sent automatically (or pingbacks if no webmention endpoint) to the indie events being responded to (multi-rsvp supported). (since 2015-163)


comics - similar to articles, except the post name is incorporated into the image and not displayed separately. The image is served wider than images in articles, and is marked up with:
fallback markup
In addition to the image, there's a further visible description, hyperlinked, semi-structured.
  • fallback markup inside the comic image describing the comic strip scene, actors, and dialog.
    • including markup of the plain text post name (p-name) which is otherwise reflected in the comic image.


photo posts are similar to notes, but start with a photo image URL which is then automatically marked up with u-photo. Supported since 2015-244 (though older notes starting with images may have been upgraded to photo posts). Full bleed photo styling on home page recent posts stream since 2015-346.


video posts are similar to photo posts, but start with a video URL which is then automatically marked up with u-video. Supported since 2015-346 (though older notes starting with videos (if any) may have been upgraded to video posts).

manually POSSEing via silo UIs before that
since 2015-12-14 to Twitter and 2016-025 to Flickr.


event posts are similar to article posts, but with explicit datetime start and optional datetime end, location (venue), and host. Supported since 2017-06-25.

  • Automatic POSSE to Twitter with:
    • automatic mapping of known venue URLs to their equivalent Twitter @-name
    • direct ➕ Add to Calendar link
  • Displaying RSVPs supported since 2017-07-06
    • Optional manual POSSE to a Facebook event — since API removal, backfeed doesn’t work so no longer doing this in practice.
  • Auto-generated form to submit an RSVP manually! (since 2019-279)


issue posts are also similar to article posts, but with explicit reply to the source code repo or its issues page, e.g. on GitHub. Supported since 2018-052 with POSSE to GitHub.

Rather than posting directly to GitHub, it is better to post any new issues (or comments on issues) on my site first, and then automatically have those issues and comments be syndicated to the right repo or thread accordingly. (per http://tantek.com/2018/015/t1/made-destination-figured-out-newwwyear)


  • github.com: plenty of groups/repos for standards (microformats, W3C, WHATWG), open source projects (various Mozilla projects, indieweb, microformats repos) use GitHub, thus this feature enables owning your issues for those and any other public GitHub repos/projects.


IndieWeb Friendly

Falcon supports the following IndieWeb friendly interoperability and other best practices:

Standards Support

Standard publishing formats:

Standard protocol support:

Auto-archive links to Internet Archive

Falcon automatically pings the Internet Archive to save a copy of any links in notes & responses (see: Trigger Archive in PHP for details).


Falcon currently supports automatically POSSEing to:


Open Source

Q: Is Falcon open source?

A: Falcon is a mix of open source and closed source. The open source portions are currently published in the CASSIS JS/PHP library, in particular as building block functions which may be useful to other indieweb projects.

As work on Falcon develops, more and more of it is made open source.

Installable by others

Q: Is Falcon installable by others?

A: Currently no, Falcon as a whole is not installable by others, and that's not a primary goal currently. See #Working On to see next goals for Falcon.

Publishing UI

Falcon publishing UI currently consists of the following:

  1. BBEdit (your choice of text editor) write new post in the storage file directly (see below for storage file format)
  2. Terminal scp (securely update storage file on server)
    • at this point the post is live on the site, including permalink, home page (if among recent posts), Atom feed
  3. minimal verify, PuSH, POSSE web UI that:
    • Requires and redirects to HTTPS access and uses a secure cookie (just for the admin UI) per https#Level_2_security
    • Uses RelMeAuth for sign-in
    • provides a text input field for a tweet URL that the next post is in-reply-to
    • shows a preview of the next post (notes shown enough to fit in a tweet, auto-linked; only articles' names are shown. Both represent what will be tweeted in the POSSE step).
    • provides a button (Tweet it) which when pressed, submits the form and does all the
      • PuSH sending,
      • POSSEing to Twitter, and
      • saving resultant Twitter syndicated copy URL to storage.

Sample Post Creation Flow

2015-181 sample post (e.g. [3]) creation flow:

  • open local copy of current bim storage file
  • copy/paste note markup template
  • update date (and nth note number if > first note of the day)
  • update time expected to post (good to have a rough estimate if I forget later)
  • find previous related post to link to (if any)
    • Write "Previously: " and link to it
  • write note text content
  • edit for how it’s likely to get ellipsed when POSSEd to Twitter
  • go foursquare.com/t/history to get a related photo (if any) to make a photo post
    • right-click on a photo and choose "Copy Image Location"
    • copy-paste img src URL into note then type () and paste URL again and press return
    • change 472x236 in first URL to width960 and in second URL to original for typical full 1920x1440 resolution
    • write descriptive alt text inside the ()
    • repeat for any additional photos to make a multiphoto
  • update note published time to present
  • save bim storage file and scp it to server
  • go https://tantek.com/falcon/
  • review POSSE tweet preview
  • click "Post"

PHP support

Falcon has some code to support various PHP configurations (and sometimes misconfigurations, such as missing local session file path).

Legacy support

Falcon supports the following legacy technologies for specific use-cases.


Falcon supports:

  • Atom/XML with ActivityStreams object type annotations: "article", "note" from [4] (note: Falcon supports reply, RSVP, and like posts yet they are all just object-type "note" in the AS output).
    • Use-case: Tantek.com Atom feed of articles is consumed by Planet Mozilla. (using ?ot=article)
    • Use-case: Tantek.com Atom feed of articles + notes (includes photos) is consumed by micro.blog (using ?ot=article,note), specifically to exclude like posts per 2019-05-21 feedback. Note that all reply (e.g. including issue and RSVP) posts and event posts are also excluded.
  • PuSH notifications of Atom feed updates when posts are published using Superfeedr's https://pubsubhubbub.Superfeedr.com/ hub (since 2015-03-18, previously used Google's hub at pubsubhubbub.appspot.com since 2010-02-01)
    • Use-case: Status.net / Identica subscribers get real-time updates via PuSH notifications from tantek.com and make use of note vs. article distinction.
      • E.g. Quitter.se users are able to directly subscribe to this Atom feed, and see posts within seconds since they receive PuSH notifications (verified by Kyle Mahan 2015-04-25[5]).

Bug Reports

If you see something broken, add a note here and I'll look into it. thanks! - Tantek Çelik

Working On

The next things I'm working on designing and implementing in Falcon. These are all things where I have made some progress with UX, code etc. and thus am "in the middle of" implementing. Roughly ordered by personal priority.

improve photo posts

I hastily implemented photo posts on 2015-244 as an impulsive itch scratch of wanting the Bridgy Publish Facebook POSSE copy of my "note with photo" to look better on Facebook [6], and then later 2015-312 implemented automatic Bridgy Publish POSSE of photos to Facebook and Twitter! Then Facebook dropped their API 2018-08-01 and I stopped POSSEing to Facebook.

There are several key improvements (beyond the default mobile presentation - see above) that I want (and some that I explicitly postponed at the time).

mobile friendly recent photos box

As of IWC Austin Project Day, I have a recent photos embed on my home page!

Possible (unordered) improvements to consider:

  • show overlaid "stack" icon/emoji like IG does on thumbnail of first photo of multiphoto posts
  • OR most recent photos, including all photos from multiphoto posts
    • leaning towards this one, as I kinda dislike that the IG approach 'buries' 2…nth photos of multiphoto posts on the summary profile page etc.
    • OTOH, I kinda like the way the current embed does show a broader range of posts, otherwise it might show just two posts worth!
  • For mobile perhaps a simple row of only 3 square cropped/shaped photos, similar to the sizing in Instagram's profile view.
  • Show only photos I've taken — exclude photo reposts (once that's a thing I support)

Clicking on the "Recent photos" heading should go to a photos-only stream view, similar to Instagram's one photo full-width on the mobile device view.

mobile friendly photos only stream

I want a separate photo stream page on my site

  • likely "/indieweb/photos"

that looks

  • at least as beautiful as Instagram for browsing through recent photos on mobile
  • at least as beautiful as instagram.com/tantek for browsing on desktop

Why: I think showing such a page will start to demonstrate the power of owning your own design on the indieweb - and how we make things just as beautiful as any app.

And I know for one thing at least my parents will use it.


  • webaction buttons that let them "like" or comment on the photo on Instagram

While not ideal - it provides at least:

  • some interaction/UX
  • visual cues that help the scrolling list of photos "feel" as nice as Instagram

And then have that link to my photo grid page.

  • OR have a photo grid vs photo stream toggle, again like IG (used to have)
    • perhaps with only CSS and fragment links and :target selector?

mobile friendly photo grid

Implement a mobile friendly:

document how and why photos

Document on this page, the specifics how to do photo posting (current required user flow)

New photo post process (as of 2017-088)

  1. Any time: take photo(s) when the moment calls for it
  2. Right after: quick checkin to Swarm (sticker only, no description/pix) to the venue where I took the photo(s) to record a spacetime coordinate
  3. When bored: edit/curate photos locally on device
  4. Later at fast wifi: upload (edited) photo(s) to respective Swarm checkins
  5. Later on laptop: Create photo post (or multi-photo of same venue photos) using Swarm width960 jpg for display, link to full "original" 1920x1440 resolution
    • Automatically POSSE to Facebook (until 2018-08-01), Flickr, Twitter
  6. Optionally manually POSSE to IG:
    • Open Twitter app, go profile
    • Tap photo POSSE copy
    • Select all text, copy
    • Open Instagram app, create photo post with local photo, paste description incl permashortlink copied from the POSSE tweet.
    • On laptop: open Instagram profile, click on latest photo, copy URL, add "u-syndication" link to it on my original photo post, scp update the photo post

Why post photos? Document the motivating use-cases for posting photos, publicly, privately, realtime-ish, after the fact, etc.

Document some specific why material about the current design, and ongoing motivations for photo posting design:

  • Three motivating use-cases (the first two motivated me, third was an afterthought)
    1. Reduce annoyance/frustrations with the Instagram iOS app crashing repeatedly (since/on 2017-085)
      • why switched from manual IG PESOS to Swarm PESOS: I started to explore other mobile photo posting UIs, and discovered that Swarm posted photos have much higher resolution (original?) as compared to Instagram.
    2. publishing photos with resolution high enough for laptop backgrounds / screensavers
    3. POSSEing of higher resolution photos (than the reduced resolution JPGs hosted by Instagram)
    4. wanting to publish more photos (on my site, POSSE Flickr etc) than on IG
  • low-latency / in-person interruption to photograph moments, capture location & time
  • no pressure to "insta"-post
  • option to provide high-res (1920x1440) pictures for desktop/screensaver use
  • minimize steps

cluster photos

Sequential photo posts that are related (typical) should be clustered in displayed in-stream.

Wrote up some thoughts here on:

Should multiphoto posts be shown with photos clustered as well?

Should adjacent mulitphoto + multiphoto posts be clustered at all?

Or adjacent photo + multiphoto or multiphoto + photo posts?

person tags

I really want to

I also really want to:

photo web action fallbacks

(reprioritize "improve photo posts" at this point) Consider providing Instagram/Flickr/Twitter web action fallbacks (options?) for photo posts, e.g. to

  • like a photo or
  • person-tag it? e.g. tag-of response (postpone)

own photo src URLs

Create photos.tantek.com URLs (or other subdomain) purely to own the actual img src= URLs, regardless of where I statically serve them from, whether 4sq or S3 etc.

improve photo permalinks

My photo post permalinks are good, and their design can be improved:

  • analyze other photo#IndieWeb_Examples
  • consider what to show at the absolute top (date? my icon/name? location? date? why?)
  • ..

Recent Articles improvements

The Recent Articles box on my home page can be improved a number of ways.

  • Re-use common code between Recent Articles box and articles-only Atom feed

And while in there, consider:

  • #mobile_recent_articles_box
  • "More articles..." link that goes to a separate articles-only page of the most recent (perhaps 10?) articles
    • at what URL?
    • link rel alternate link from that articles-only page to articles-only Atom feed

mobile recent articles box

There have been enough times that I've referred to recent articles in a mobile context (while walking around with someone) on my or another's mobile device, that it would be useful to move my recent articles box to the top of my site even in the mobile view. Longer term, such a box should simply be a movable Falcon template item.

articles only stream page

The header for the recent articles box (and a "More articles..." link after the list of recent articles should link to a:

  • "articles only" stream of recent articles
  • perhaps at tantek.com/articles

for anyone that wants to read a scrolling list of my recent blog posts (e.g. load it while connected, and then be able to read for many minutes (hours?) when on a subway or plane etc.)

Perhaps build it as a variant of my photo stream, just with a different "type".

minimize Bridgy Publish links

Implement Bridgy#Minimize_Publish_Rerequests and document my techniques / code there so others can also do so. Part of treating a shared volunteer service like Bridgy kindly/politely, shared care for part of our broader IndieWeb commons, setting an explicit example by doing so.

named pages

Named pages (used to be captured as an Indie Wiki itch) are pages on my site that have a name as their primary identity, instead of being primarily identifed by their date of being posted (as posts are).


  • a mechanism to handle editing and display of "simple" pages that may or may not have versioning. E.g.
    • /contact page
    • /pay page
    • a speaker's bio (currently using PBWiki for this)
    • ...
  • lots of "wiki-this" content in local text files where they're more convenient than dealing with a slow online service, however, slso heldback per:
    • feeling of creativity being heldback (by putting stuff in local files) per [7]
      @scottjenson: Personal epiphany: Locking my creative output into opaque files and using the Finder to organize it is massively holding me back

Reduce annoyances with existing setup:

  • feeling icky about hosting my personal wiki on the PBWorks wiki silo
  • tired of not being able to edit it on mobile
  • disgusted with the ugly PBworks URLs
  • dislike the PBworks UI
  • PBworks latency too high

First level solution:

  • Named pages handled by Falcon doing all routing for all URLs (inside the folder its in and children thereof. e.g. if falcon.php is at the root then it handles all site URL requests.)
  • Smart defaults that make authoring easy:
    • automatic site header, footer, style sheets to make it fit in with site design/theme
    • No title element? Look for an h1 and synthesize it from that

Next gen: have every page on my site by default be a wiki page made "wiki-like" by Falcon, where wiki-like means:

  • editable with web UI on any reasonably modern web browser, not requiring javascript
  • browsable version history (maybe with web sign-in only? no need to index version history)
  • browsable versions (maybe with web sign-in only? no need to index old versions)
  • some method of auto-syncing local text file copies of such pages (as simple as or better than Dropbox sync of a local folder)

Brainstorm started here:

improve offline support

Added offline support on 2019-10-21 per https://tantek.com/2019/293/t1/indiewebcamp-brighton-hackday-offline

More offline / service worker support:

  1. what Jeremy got working with Going offline with microformats
    1. start with https://clearleft.com/offline inline script near the end
    2. sort them by URL string order
    3. get actual post name or summary
  2. document my example and "levels" on offline#Indieweb_Examples
  3. document possible IndieMark levels for an “Offline” category based what I got incrementally working.

Design, document, and implement three levels of offline support depending on user interaction:

  1. Permalink posts (e.g. referral from search engines). No expected relationship with user, so no pre-caching of content. Maybe minimum service worker with *only* offline page and cache as you go for home page only, so that if it is loaded next, it gets cached.
  2. Home page visit. User is visiting me, not just a post, and thus is starting to build a relationsip. Existing service-worker that precaches /contact /pay and adds cache-as-you-go to all other pages
  3. PWA install. User has gone to the trouble to *install* my site. Precache all my post content storage files through 2010 up to the most recent 5MB. Precache recent photos. Enable offline page to dynamically render any permalinks from my cached storage files.

improve replies details

improve reply-context support

Currently works for showing all in-reply-to URLs (union of explicit rel-in-reply-to and u-in-reply-to markup), with a bit of smarts to show type of response (in reply, RSVP etc.).

Necessary improvements:

  • consider using XRay (X-Ray) at post publish time (falconpost UI) to
    • synchronously get reply-context information statically
    • fall back to get author info (icons, etc.) from a nicknames-cache
    • display richer reply-context in falconpost UI - editable!
      • everything from XRay
      • get u-syndication for Twitter if any from XRay and auto-fill tweet reply-to field!
      • allow editing of fields! default as input text
        • content: auto-truncate (what is good max for reply-context? 280 char tweet length?) and present in a textarea! (use-case for a "Reset" button, reloads the original)
        • name: auto-truncate also 280 char
        • author name: e.g. Twitter visible names often odd or indicate status (like @ XOXO)
        • author icon: e.g. undesirable Twitter icon, allow removing. or temporary campaign (banner on image, or solid color etc.) replace with another img URL, and eventually auto-fill from a nickname cache
        • dt-published: no edit, unless: if in future or erroneously (1969?) in past then show erroneous and input type of date/time set to present time (in case it is a correctable error)
    • save that reply-context info as h-cite inside post storage alongside links to POSSE copies (Twitter, etc.)
    • display higher fidelity reply-contexts
    • Store and show dt-published of original post
    • Store and show full name of author of original post
    • Store and show tweet text / p-summary of original post
      • distinguish presentation of a multi-reply to the same post+POSSE copy, vs multi-reply to different people/posts.
    • similar improvements to compact in-stream reply-contexts
  • Start a nicknames-cache implementation


  • Provide readers better reply-context of the URL (or URLs - see multiple-reply) I'm replying to. Better user experience through increased comprehension from the provided context.
  • show higher-fidelity reply permalinks, similar or better than Twitter @-replies
  • Building blocks for comments: all of this code serves as building blocks for comments-presentation.

Some of this is harder than other improve replies features, and doing reposts, so reprioritize as necessary with remaining "improve replies details" tasks

show fragmention blockquote

  • consider showing blockquotes in reply-contexts in reply to fragmention URLs.

reply-contexts in archives

Prefix reply posts in archive lists with ↪ inline linked to the in-reply-to URL with u-in-reply-to, similar to existing in-stream reply-contexts on home page!

Example of expected usability / presentation benefits (and arrow icon shape confirmation/re-use from an earlier design)

post reply to any URL and auto POSSE

Do u-syndication discovery of POSSE tweets in posting form / UI to support POSSE Replies to Twitter


  • Automatic POSSE threading - automatically thread the POSSE copy of my reply with the POSSE copy of the original indieweb post that I was replying to.
    • enter just the URL of an original indieweb post I'm replying to into my posting storage (or UI),
    • have Falcon's posting UI automatically discover the link to the tweet copy of the post
    • add an in-reply-to link from my post to the tweet I'm replying to
    • have my reply POSSE copy thread with the POSSE tweet of the original.


  • Save time and steps! Remove step(s) of me having to look for the "also on twitter" link on an indieweb post and explicitly copy/paste it into my storage/UI.
  • Preserve POSSE threading use-cases like: Provide better user experience for those reading my posts on Twitter by providing them the threaded context right there in their reading experience.

post reply to any tweet and auto indie-post reply

Do original-post-discovery in posting form / UI (approach: use original post endpoint from server)

  • So I can:
    • enter just the URL of a tweet I'm replying to into my posting storage (or UI),
    • have Falcon's posting UI automatically discover the link to the original post (that the tweet is a copy of)
    • add an in-reply-to link from my post to the original post I'm replying to, before the in-reply-to of the tweet
    • while still having my reply POSSE copy thread with the POSSE tweet of the original.
  • Why?
    • automatically link from my posts to more indieweb posts instead of their Tweet POSSE copies - prefer linking to indieweb original content and URLs
    • remove stress of having to check a tweet manually to see if it has an indieweb original version - less thinking about having to find an original permalink myself manually.

show webmention results

In Falcon posting UI, upon succssful publication:

  • show webmention results - Perhaps show a list of outbound links with send result for each (no webmention/pingback endpoint found, or green checkmark webmention/pingback sent, or red webmention/pingback rejected, distinguish webmention/pingback for each)
    • Why?
      • UIs that provide feedback on actions instill more confidence that the actions took place (similar to providing the tweet permalink of a successful POSSE to Twitter).
      • Debug/diagnose possible problems with other indieweb sites (may expand later into part of the whitelist, webmention+howyouknowme protocol/UI)
      • Convenient UI to specifically check (click-on) links with successful webmentions to see if they parsed my reply into their comments section correctly or did something else with it.
      • Might help discover sites with newly added webmention/pingback receiving support.
      • Could help demonstrate/explain how webmentions work
    • Perhaps use summary and details elements to hide by default. Presumably when everything is usually "working"

RSVP reply-context

Currently my RSVP posts have a reply-context of RSVP yes/no/maybe/interested and summary/summaries derived from inspecting the URL(s) of the event(s) being replied to.

improve rsvp reply notes

Improve rsvp reply notes:

  • use presence of p-rsvp to display an RSVP differently than a simple reply - more calendarish.

Goals (in order of design need / ease of implementation)

  1. display a nice mini-event reply-context (needs design)
  2. use whatever information can be inferred from the prose of the RSVP post
  3. parse with XRay event permalink for event information as h-event
  4. pick next most important piece of information to display and implement it. repeat.

Goals, show one or more of these,

  • improve reply-context presentation, e.g. consider "↪ 📅 (event URL)"
  • name of the event (perhaps inferred from (smart)quoted or titlecapped text following RSVP recognition prose (e.g. "going to ...")
  • date(s) of the event
    • default single day (not multiple)
    • default same day as RSVP post
      • exception: "went to" assume day before RSVP post
      • recognize today, tonight, yesterday (other textual date shorthands? analyze existing RSVP posts)
  • start time and end time
    • default no specific time(s)
    • first n:nn or nn:nn text indicates start time
    • second n:nn or nn:nn text indicates start end time
  • location
    • default no specific location
    • first @-reference possibly? indicates Twitter account of venue
      • look it up in nicknames-cache?
      • or just hardcode an array of common @-venues for now
    • if " at " in text, then use subsequent titlecapped text as location string
    • city
      • imply from @-venue
      • if titlecapped text, split on commas, work backwards from end
        • note&drop country if any, note&drop state name/abbr if any, next chunk is city name
        • use abbr title="city, state, country (if any)" and city

one-off tag-of post

Post a one-off tag-of post to provide a real world example that uses the tag-reply GitHub POSSE support by Bridgy Publish.

E.g. post tag-of responses to add labels to mf2 parsing issues:


Example labels derived from mf2 change control and h-entry change control:

Needs next steps
Unclear what is the next step for an issue, possibly yet to be classified
Needs design or proposal
new issue that needs a design or proposal to solve it
Needs tests
has proposal but needs tests to demonstrate and try it out
Needs tests review
has tests but needs review of those tests to make sure they represent the design or proposal accurately
Needs proposal review
has proposal but needs feedback and positive reviews
Needs iteration
has critical feedback or negative reviews and needs iteration on a proposal
Needs implementer review
has proposal but needs 2+ explicit positive reviews from implementers
Needs implementation
has proposal and tests but needs an implementation that passes the tests provided to demonstrate implementability and efficacy of proposal to solve the issue
Needs specification editing
has proposal. For mf2: also has tests, rough consensus including 2+ implementer reviews, 1+ implementation; for vocabularies: also has 3+ publishers and 3+ consuming implementations
Needs publishing
proposed feature needs a real world publishing example(s)
Needs consuming implementation
proposed feature needs a real world consuming implementation
Needs 3 publishers
has 1+ publisher, needs 3+ publishers
Needs 3 consuming implementations
has 1+ consuming implementation, needs 3+ consuming implementations

And similarly for removing tags:

event posts

Improve support for publishing event posts (with presentation goal similar to event#Before_2014-02-07), essentially:

Need to:

  • re-prioritize remaining what is not yet done


    • p-organizer - show first one
      • optional: display more than one
    • event description
    • who is going/maybe/invited (h-cards)
    • event activity and responses (event creation, comments, likes)
      • receive webmentions for this (will likely keep using webmention.io to queue them up)
      • manual acceptance / copy-pasting of RSVPs onto the event
      • (semi-)automatic acceptance of RSVPs
  • home page: have them automatically appear as part of my stream/home page at the event start time
  • upcoming box: have the next 3 upcoming event+RSVP(yes|maybe) posts automatically appear on the "next 3 events" box on my home page

process and show webmentions

As part of implementing "event activity (event creation, comments, RSVPs)", Falcon will have to process all webmentions received, parse/store them (with appropriate caching), and make them available for posts to display (as likes, reposts, comments, and RSVPs).

E.g. https://webmention.io/api/links.jf2?perPage=1000&target=http://tantek.com/2017/183/e1/sunday-yoga-presidio (apparently same as mentions.jf2)

Consider also:

  • webmention to email[ (both as notification system, though XMPP would be preferred, and as a backup for webmentions - could format the emails similar to how Facebook formats its notification emails)

POSSE events

IndieWeb event posts must be POSSEd to both reach friends not yet on the indieweb, and save time with copying event information to other locations. Four specific (semi-disjoint) use-cases:

Always POSSE semi-public events to:

  • Twitter (using event microsyntax shorthand) - serves as replacement for RSVP and its POSSE to Twitter
    • add features:
      • other attendees (co-organizers, speakers)
      • invitations — explicitly invite by @-name in the event post (as long as there is space)
      • hashtags — read all p-category from event post, and POSSE as hashtags in the tweet (after invitations, first one being "the" event hashtag, as many as will fit)

Specific use-cases:

Display RSVPs summary

Display summary of number of people going and interested like:

  • "3 Going · 3 Interested"

just above the facepile of RSVPs

Use Webmention.io API to retrieve # of people going, # of people interested, and turn it into HTML. (implemented per gh wmio #82)

JSON API example:

  "count": 47,
  "type": {
    "invite": 26,
    "like": 11,
    "mention": 1,
    "reply": 1,
    "repost": 1,
    "rsvp-maybe": 1,
    "rsvp-yes": 6

(summary totals from e.g. https://webmention.io/api/mentions.jf2?perPage=1000&target=http://tantek.com/2017/183/e1/sunday-yoga-presidio which shows all responses)

  • Need PHP/CASSIS to parse out the rsvp-maybe and rsvp-yes fields from that JSON into $rsvp_yes and $rsvp_maybe.
  • CASSIS to generate summary something like
$rsvp_summary = strcat($rsvp_yes>0 ? strcat($rsvp_yes, ' Going') : '', 
        $rsvp_yes>0 && $rsvp_maybe>0 ? ' · ' : '',
        $rsvp_maybe>0 ? strcat($rsvp_maybe, ' Interested') : '');

HTML5 semantic elements for accessibility

Add the following HTML elements to post permalink, post archives lists, and home page for their documented positive impact on desktop screen readers:

  • article - around each h-entry
  • header - maybe around reply-context and author h-card?
  • section role=search - around search input form
  • nav - around prev/next sequential navigation links
  • main - maybe if it has the same impact as "Section role=main"? needs research
  • footer - for datetime stamp, tagged in post / tags, maybe citation UI

While adding, document work necessary and how it would/could be improved if such markup came from templates instead per #Template_all_pages task.

Template all pages

Create templates for all pages created / returned by Falcon.


  • short term:
    • identify page types (verify with falcon.php code review)
      • fix archive pages to have without query params
    • identify color palettes for inverses of daylight (default), Matrix, and TRON:Legacy
    • use media query for darkmode to switch between dark/light variants of each theme
  • medium term:
    • identify content modules
    • identify composite modules of content modules
  • long term:
    • zero inline HTML page construction in PHP
    • develop an HTML-native template language preferably based on prior art, perhaps using a microformats2 design.


  • atomic content boxes layout
  • composite content boxes layout
  • page layout


  • page types:
    • home page
    • post permalink
    • archive specific post type on a day, all posts on a day, new month, year
    • Atom feed file
  • color palette semantic labels
    • post content text, link text, visited text
    • post background
    • post info text, link text, visited text
    • post webactions text, link text, visited text, form input field
    • reply-context text, link text, visited text
    • reply-context background, border

tags with spaces


  • setting or adding labels to issues (typically on GitHub) that are already using labels with spaces in them.
    • Enable automatic Bridgy Publish POSSE a hashtag to GitHub as a Label (which may have spaces), on tag-of replies (which itself is a separate implementation task!)
    • Example existing labels with spaces: W3C Process: Needs Review, (examples needed from CSSWG, SocialWG repos/issues)


  • Mediawiki-ish style: hashtag underscores (_) converted to spaces for their equivalent "category", with exceptions:
    • NNNN_NNN, NNNN_NN_NN = dates, convert those to "-" (perhaps convert any *N_N* to *N-N*)
    • X__Y treat as literal "_" and convert to X_Y
  • OR Backcompat: hashtag double underscore (__) convert to space for their equivalent "category". Notes:
    • "__" rare (not used?) in hashtags today (certainly not in any more my posts)
    • maintains any/all existing X_Y single underscores (no exception needed for NNNN_NNN, NNNN_NN_NN to avoid conversion into spaces between numbers)
    • optional convert any *N_N* to *N-N* because actual ISO Date category names YYYY-DDD and YYYY-MM-DD read nicer than with underscores, and numbers rarely (if ever?) use underscores for separators for anything meaningful, whereas dashes between numbers are common in serial numbers, product codes, confirmation numbers etc.

auto-tag markup if there are any double underscores:

  • #tag__with__spaces

Document chosen design as a brainstorm:


  • Implement space separated labels via __ or _ per design above in hashtags, in auto-tag function
    • 2019-058 implemented __ per design but did not yet deploy. Waiting for real-world use-case to try it out (might need to implement tag-of reply to start labeling microformats2 parser and vocabulary (e.g. h-entry) issues to exercise labels with spaces).
    • 2019-070 debugged and deployed. fixed remaining syntax bugs and deployed with no regressions in existing tags, and functional tests, but have not yet tested __ hashtags in practice with a real world example post that is then POSSEd to GitHub or Flickr.
    • ... actual real world post with __ hashtags POSSEd successfully to GitHub and/or Flickr with spaces in the labels/tags there.


better post creation UI

Iteratively incrementally improve Falcon post creation UI.

Current: hand-editing flat file HTML+microformats storage file to add a new post.

prototype DM UI


  • Stage 0: start with a minimal UI to post a DM to a URL
    1. Minimimum Viable Feature
      • to: URL field
      • message: textarea
      • (Send) button
      • if it's a Twitter profile URL, use Twitter API to send the DM
    2. check private messaging for more destinations and how to handle
    3. 30 second undo! (client side)
      • Send button disables text fields, turns into Sending…:nn (Undo Send)
      • with a count down timer :nn that goes from 30 to 0
      • At 0, hide :nn counter, (Undo Send) button, use Twitter API to send
      • When it returns success, Change Sending… to Sent.
      • If user clicks (Undo Send) button, hide button,
        • change Sending… back to (Send) button
        • re-enable text fields for editing
    4. 30 second undo (client and server side — so it would work/show status across multiple clients)
  • ...

post creation UI improvements


  1. Stage 1: simplify/minimize post origin format as much as possible (to minimum that a UI would "submit", re-use minimum expected properties from Micropub)
    • scheduled post heads-up / warning: prominent heads-up in the UI if dt-published is more than a whole minute in the future.
      • e.g. "This post will be visible in xx days/hours/minutes"
      • and disable "Publish" button (since no auto-POSSEing in the future support yet)
    • warning if next post number (day scoped) is discontiguous (e.g. if next post is /t3 and previous was /t1)
    • default/auto-add "with BBEdit" content/markup even if missing; simplifies post origin format
    • store slug as visible content (instead of as part of uid)
      • then auto-generate ordinal days and post number (from previous "s" file published post number)
      • and post type: default "t", unless h-event then "e", or explicit h1 class="entry-title" then "b", or like-of then use "f",
    • default/auto-add dt-published (even if missing "published"); simplifies post origin format (I think I implemented this ~ 2017 June maybe IWS? 2017?)
  2. Stage 1.5: Document Save/Publish/Delete/Undo user flow design in create#Brainstorming (from original 2010-era notes, with updates, use-cases)
  3. Stage 2: Save/publish form submission to storage file
    • UI: Form with minimal fields to write notes, replies, likes, articles (model after Micropub clients)
    • Server: "Save" submission to store in post origin storage (perhaps with dt-created)
    • Server: "Publish" submission to do "Save" and current POSSE+PuSH support
  4. Stage 3: Delete/undelete saved posts
    • UI: Delete after Saving, Undelete after deleting
    • Server: Handle delete saved unpublished post, undelete deleted unpublished post
  5. Stage 4: Undo publishing
    • UI: Undo after publishing
    • Server: Handle undo after publishing -> saved state, plus delete any POSSE copies if any
    • Server: Handle publish with 30(?) second delay, so undo can happen without having to delete any POSSE copies
  6. Stage 5: Whatever else I have in my 5-6 year old UI flow sketches re: (auto-)save, delete/undelete, publish/undo
  7. Stage 5.5: interactive prose improvement highlighting / fixing support in the primary writing field. Pick and choose which of these to implement, consider open sourcing as its own library:
    • Hemingway . Investigate how much work it would be to implement an open source (licensing?) version of Hemingway App, and implement it if it can be done in a day at an IndieWebCamp.
    • words to turn around. Also implement word/phrase replacement suggestions in 2017-12-04 words to turn a conversation around
    • inclusivity suggestions. Implement suggestions for more inclusive words and phrases as documented in a table of Slackbot responses.
      • Start with AlexJS. Open source AlexJS has a bunch of inclusive language suggestions already coded/supported. Re-use and contribute to its vocabulary.
      • write-good. Open source write-good is a “Naive linter for English prose” for words like 'simply' 'easy' 'just'.
    • short codes like TypeIt4Me. Like @Zeldman summarized:
      • Typing “ttt” access to typographic symbols: ✎ ✩ ✩ ♛ ☞ ★ ★ ☞ ☛ ♛ ⇛ ❝ ❦ ❞ ¶ ✺
      • “;shrug” gives ¯\_(ツ)_/¯
    • additional improvements - one-off ideas for linting prose / suggesting
      • Actually, - When a sentence starts with "Actually ," or "Actually ", drop it and start with the next word, or if it is necessary to connect that sentence to the previous statement, replace "Actually, " with "And " or "Yes, and ", but don't if the next word is already an implied connector of sorts like "Another ".
      • Yes but - similarly to Actually, drop "Yes but", or replace with "Yes, and " or "And ".
      • ...
    • etc.
  8. Stage 6: Implement micropub client and server support, figuring out what is missing for undo etc.

UI for many drafts

Main article: draft#UI_for_many_drafts

Brainstormed this generically draft page since I think it would be useful as both a local application (where the drafts are stored in local text files) or as a Micropub client.

For Falcon, I'd likely evolve the abovementioned Post Creation UI to something web-based (offline first using local storage) with:

  • explicit support for (JS auto-saving) an unpublished draft, like Gmail (no URL? or use post status or something similar)
  • support for multiple unpublished drafts (not just a "current draft" you can come back to)
    • with a simple "pick one" list UI, click to select a draft as the "current draft" you're editing, and preserve that state on the server (which draft), as well as draft scrolling position if possible.
    • upon publishing something it's removed from the list
    • upon undoing a publishing it's added back to the list
  • hashtag buttons by frequency, clicking each filters on that one hashtag (like radio buttons)
  • clicking hashtags highlights them and adds/removes them from filtering (like checkboxes)
  • search box for filtering as well

Display Likes Reposts

Implement a minimal display of likes & reposts on posts.


  • just lists of @-names & domains
  • maybe facepiles linked to URLs with names as alt text
  • maybe counts of both and a list?
    • Is it good or distracting / emphasizing the wrong thing to show counts (like every silo does)?
  • Perhaps query webmention.io for likes and reposts separately, then pipe through stream.thatmustbe.us, and display as inline list of author names linked to their URLs
  • Perhaps process queue of webmentions at webmention.io

Display likes facepile on events

As a small incremental step, display just a likes facepile, just on event posts.

This will be a good way to experiment with presentational issues without impacting all posts.

Also I can more easily check (by hand) every event post I've posted since launching them at IndieWebSummit 2017 to see what the likes facepiles look like and if there are any that need selective blocking/deleting using the webmention.io dashboard.

Display reposts facepile on events

Once like facepiles seem to work ok on events, then see if any POSSE copies got reposted (I think a few HWC SF past events did) and implement a reposts facepile just for events accordingly.

This will also be a good way to experiment with likes+reposts facepiles presentational issues on a smaller, constrained, set of posts.

Display likes reposts all posts

These are dependent on being able to block sources and perma-delete specific (abusive) webmentions:

This is required to solve the following problem(s) which are bad enough to block deployment of displaying received webmentions:

  • a family member is reading my public post, sees a facepile of people liking my post, sees an "interesting" avatar/icon in the facepile, clicks it, and sees a bunch of ugly things. I'd really like to avoid that

Scaling display: How to handle a facepile with 100s of items?

E.g. test case, showing a facepile of the links and/or reposts on this post (100s of each)

  "count": 312,
  "type": {
    "like": 110,
    "mention": 33,
    "post": 2,
    "reply": 36,
    "repost": 128

Real world example:

Homepage mentions

Showing homepage mentions is an entirely different scale of design problem:

  "count": 101737,
  "type": {
    "like": 30,
    "mention": 99995,
    "post": 5,
    "reply": 1660,
    "repost": 4

Own my public list emails and replies

Goal: start posting emails & email replies to public lists on my own site first, and POSSEing them (perhaps manually at first) to their public email list destination(s).


  • dev-platform@mozilla
  • public-w3process@w3
  • www-style@w3
  • ...

Common design:

POSSE new emails to public lists

When I post to a public email list, I want to first post the email to my site, perhaps just like an article (maybe exactly so to start, as an MVF), but have an option to target a specific email list as a POSSE destination.

A reply that changes the subject counts as a new email too, and can still quote/comment on aspects of whatever email it was in reply to.

POSSE reply emails to public lists

When I reply to an email on a public list, I want to first post the reply to my site, like any other article reply (maybe exactly so), and set the in-reply-to to the public permalink of the email on the public list.

Ideally my server would automatically POSSE it, but I'll likely start with manually doing so.


POSSE email with images

Incremental enhancement:

POSSE any embedded content images (non-decorative, u-photo?) as attachments.

POSSE email with attachments

Incremental enhancement:

POSSE any attachments (How to publish? iframe? rel=attachment? u-attachment? see also h-event attachment feature/property)

On This Day

Implement basic on this day functionality:

  • on_this_day#Home_page_box
  • separate /onthisday page showing all posts on this (current) day
  • "Previously On This Day" footer section on post permalinks showing a list/summary of posts on that same day in previous years.
    • perhaps do only client-side with JS/AHAH to avoid causing re-indexing thrash of posts over time?
  • also include posts *about* a day, e.g. with #2018_048 style hashtags


  • I expect both emotional value and challenges - a good combination to inspire in-person discussion
  • show value of indieweb posting all your things as compared to any one silo

Display Received Webmentions

Process my queue of webmentions at webmention.io and implement some sort of comments-presentation to show them on my posts.

  1. simple date-time-ordered (oldest first) as comments below those facepiles

These are dependent on being able to block sources and perma-delete specific (abusive) webmentions:

This is required to solve the following problem(s) which are bad enough to block deployment of displaying received webmentions:

  • nonsense @-replies to POSSE tweet permalinks (happens often enough to be a problem, e.g. 2017-07-17, and 2017-09-27

Some other ways to view webmentions received by tantek.com and permalinks:

Payment Links

Additional variants:

  • tantek.com/donate
    • Use-case: a dedicated donation page, perhaps even specific to donating for "suggested donation" yoga classes.
  • Payment page with amount and what for - if possible - to prefill URLs to payment services with amount and what
    • /pay/nn/what or /pay/nn/for/what or /pay/nn/for?=what
    • Use-case: similar to just amount e.g. /pay/10/for/yoga, with less typing / entering into the payment app

one-off person-tag response to photo

Work on a sample person-tag reply post to (per person tag reply brainstorm)


  • So we can have a concrete real world markup example to test microformats2 parser improvements on.
  • And a building block for SWAT0 as well as 0.1 (person D tags B in the photo, instead of A tagging B in the photo).


  • Document all the brainstorming in IRC starting 2014-323 13:05
  • Publish a post an edit (/d..) with u-tag-of link to the photo post being tagged
    • text equivalent of above example could be detected/handled in Falcon as:
      1. starts with @-name in reply to such a POSSE tweet copy from that person.
      2. immediately following is " I see ", then the list (whitespace or comma separated) of @-mentions with optional "and/&" and/or "you", ending with " in " ("it" | "that" | "this" | "your").
      3. use "u-tag-of" instead of "u-in-reply-to"
      4. lookup @-names in a nicknames cache to convert to full name / indie URL for original post.
      5. send webmention to original post and to each indie URL home page.
      6. post POSSE copy with @-names to Twitter.
  • Display person-tag-of post
    • reply-context with the thumbnail of original photo (hotlinked) (see FB screenshots)
    • markup as documented above
    • fallback markup/text for consumers that
      • don't support tag-reply (that treat it as a plain reply)
      • or don't support person-tag (that only see the tag text)


  • Document all the brainstorming in IRC starting 2014-323 13:05
  • Publish a post
    • image map and area elements connected to that photo
    • fallback markup/text for consumers that
      • or don't support area-tag (i.e. that don't yet parse microformats2 on area elements)

Previous thoughts:

  • Publish a post, an article reply since it's a reply, and article since it has non-trivial markup.
    • (what's the name for the the article?)
    • should instead be able to do with a note/reply, auto-converted

pinned posts

I want to implement pinned posts for the use-cases of:

... at the top of my stream on my homepage.

See: pin#Brainstorming for some of my current thoughts.


  • global? a simple one pinned post on a homescreen could be stored as a global URL to the post permalink of the pinned post
  • per post property: better would be a per post "pinned" property which could take multiple values, either
    • string of a tag name to pin on top of that tag page
    • perhaps "/" meaning homepage stream pin
    • or "/path/" arbitrary paths to pin the post (could be useful for pinning a post on a specific archive page etc.)

POSSEing pins:

  • Ideally when you pin a post on your homepage, your server software should automatically pin any POSSE copies of that post on their respective silos, e.g. Twitter
    • Is there a Twitter API to pin a post? Should I code this myself in my UI or file a Bridgy issue or both?
  • Similarly with unpinning

Upcoming Events Based on RSVPs

Find next three current/upcoming events by looking backwards through storage for RSVPs (max 3 bims? no RSVPs more than 6 months in advance AFAIK).

  • like most recent three articles box, except need to check RSVP for end-date if there is one, or if not then start-date, is today or later

Use information inferred to create RSVP reply-contexts to generates summary events for "Upcoming Events" box.

send webmentions for other links

Send webmentions for other posted links (beyond links I'm replying to, e.g. mentions, likes, etc.)

  • Why?
    • Key building block for indie likes, reposts, quotations and other response post types
  • Why also?
    • To comment on IndieNews posts (assuming I have rel-in-reply-to links to IndieNews URLs implemented) as a proof of concept of an indieweb-friendly comment aggregator/threader.
  • Why?
    • Enable syndicating posts to IndieNews (assuming I have u-syndication links to IndieNews implemented - perhaps as post option in my UI). Help demonstrate IndieNews as a proof of concept of an indieweb-friendly link aggregator.

Select Text Fragmention UI

Add JS that enhances text selection by providing a fragmention link to copy to reference that specific selected text.


  • Encourage more linking to fragmentions
  • Explore more fragmention use-cases / UI (especially at a IWC/IWS)

Update Delete UI webmentions

Webmention.rocks has helped motivate me to get a minimal UI working for updates and deletes! In particular in my Falcon posting UI:

  • Deletes
    • Detect when storage has a (new) delete of a post (compared to what was last posted)
    • Prompt user to "Confirm Delete"
    • Send Webmentions to links in last version of post before deletion
    • Update stored version of post to tombstone
    • Figure out deleting POSSE copies
      • call Twitter API to delete POSSE tweet
      • request Bridgy support deleting POSSE copies of FB, Flickr, Twitter etc.
    • Verify webmention.rocks Delete tests
  • Updates
    • Detect when storage has an update to a post (compared to what was last posted)
    • Prompt user to "Update Post"
    • Send Webmentions to links in previous version of post and new version of post
    • Update stored version of post
    • Figure out updating POSSE copies
      • If update is within a minute(?) and text-only: delete previous POSSE tweet and rePOSSE updated post
      • Updated photo posts: Bridgy won't rePOSSE same permalink
      • FB: no update API / Bridgy support :/
      • Flickr: update API (postpone) / no Bridgy support :/
    • Verify webmention.rocks Update tests

mobile design

Update default CSS to look awesome on mobile / small displays, including:

  • homepage
    • better dividers between posts in-stream
      • expand post footer beyond date published, e.g. with webactions
      • indent the dividers between posts (wide layout only?)
      • mobile: use vertical white-space (2 whole linebreaks) between posts

and permalinks of:

summary more text UI

Implement summary#More_text_UI to:

  • Enable excerpting my content for POSSEing
  • in particular when POSSEing to FB using Bridgy
    • Switch to Bridgy for all my FB POSSEing and turn-off Twitter->FB auto-crossposting for these reasons:
      • 1. Stop having to manually delete the Twitter->FB auto-crossposts for photo posts
      • 2. Twitter->FB of notes can be annoying[8] to others:
        “Here's a friend crossposting from Twitter, so all these @ tags don't work.”
    • Often only want to post some of my notes text (more than tweet POSSE but not entirety of note text) to FB


  • support "More..." text in its own paragraph in the content as the "UI" to designate a summary boundary
  • add a new CASSIS function or option to existing auto_link function to auto_summary based on that "UI"
  • update calls to auto_link in Falcon to use that new function/option to provide p-summary markup in permalinks (e.g. so Bridgy Publish can see them), and maybe on home page so readers can see them.

repost support

reposts of Instagram posts

Instagram itself has no native "repost" feature. Thought there are some 3rd party apps that you can use to repost something on Instagram.

I want to be able to repost others’ photos from Instagram to my own site, and then:

  • POSSE that photo to Twitter, with proper attribution to original author
    • requires Instagram -> Twitter identity correlation
    • document existing repost#Silo_Examples on Instagram using 3rd party tool, what graphical / textual conventions they use
  • POSSE that photo to Flickr, as photo post but with proper attribution to original author / permalink
    • figure out how to best use Bridgy Publish to post a photo post with custom text for a repost

reposts of indieweb posts

Implement reposts of indieweb posts, and POSSE syndicated copy:

  • Why? So I can repost native indieweb posts, and if they have a u-syndication link to tweet, then as part of POSSEing my post, the tweet of the original can be retweeted!

reposts of tweets

Implement reposts of tweets:

  • Why? So I can retweet tweets from my own site (rather than directly on Twitter), keeping a copy of the retweet on my own site, while still POSSEing the retweet on Twitter, so the original tweeter sees that I've reposted/retweeted it.

simple repost of tweets:

Recently (2014-06-04..05) I was at a conference where I wanted to retweet a quote someone else captured from one of the speakers rather than make a similar post myself.

However this time I reached the point of not wanting to just retweet on Twitter any more - I wanted to retweet it from my site, thus keeping a copy on my site, while still POSSEing a native retweet on Twitter.

In short this means implementing:

  • Detecting storage of a u-repost-of property
    • treat first instance as canonical / primary, which can be loaded (following redirects) to get the original post
    • additional u-repost-of properties are assumed(required) to be the repost chain all the way to the original post.
    • keeping the retweet chain is useful in case one of the intermediate accounts is deleted
  • Posting UI - alter Posting UI accordingly for reposts of tweets
    • No character count
    • No ellipsing
    • Retweet rather than Tweet button
  • POSSE call Twitter retweet API rather than update API
  • Save POSSE URL - save new retweet tweet id as rel=syndication into storage, so web action buttons work properly
  • Presentation for a repost
    • See 2014/reposts#Repost_presentation for details of what and how to present a repost including:
    • icon of original poster
    • original tweet posting time.
    • some sort of retweet icon to indicate that it was retweeted by me
    • time when retweeted (perhaps near retweet icon and an icon of myself)

quote posts

I've been wanting to post quotes with minor secondary commentary / summary, and thus have been brainstorming a bit about how to do so.

  • based on a note
  • u-quotation-from on link to source of quote (similar to "u-like-of")
  • storage:
    • quoting part of:
    • quoting entirety of:
  • publishing:
    • similarly use u-quotation-from vs u-quotation-of
    • write this up in quote "How to Markup"
    • issue when to use vs u-quotation-of (implies quote of whole of destination)
    • use u-quotation-of when quoting an entire note/tweet
      • detect that when POSSEing, and use quotation#Bridgy to POSSE instead of Twitter API
    • use a fragmention when quoting from part of a specific paragraph; with a long enough fragmention, you could always provide a URL to the entirety of what you are quoting
      • those that display marginalia can display "quotes from" responses too
      • perhaps write up "How to display quotes from responses to your content"
      • Kartik Prabhu says he could add a "quoted by" section in the responses section of posts (and perhaps similarly for paragraph marginalia - also for likes/reposts of paragraphs)
      • FAQ from Kevin Marks "Does a fragmention reference imply a quotation-of? No, fragmentions do not / should not imply quotation-of - based on existing data/usage - fragmentions are mostly replies (e.g. see Kartik's examples) and some mentions."
  • automatically blockquote text surrounded by “ ” smart double quotes (keep the quotes)
  • POSSE partial quotations of tweets as an @-reply to the original tweet


meme posts

Publish a sample meme post similar to my comics post support, with:

  • summary: text of the meme object (exact text that is overlaid on top of the meme image)
  • content: consider techniques for providing description of image and text as alternative to image inside the meme object
  • no post name/title (thus more like a special type of note)
  • how to POSSE a meme post to Twitter
    • text and upload image
  • document "Why" and "How to markup" in meme accordingly

indie-config loading

I'd like to add indie-config loading support to my existing webactions so that any registered web+action: URL handler is automatically activated, e.g. for:

  • Seamless "Reply" user interaction, from my posts, to anyone whose website is setup to handle web+action: URLs.

I believe I can do this by following the how to as documented in:

And then should be able to test it with Aaron Parecki or Kyle Mahan's implementation of web+action: URL handling, or rather, have them test it by going to one of my posts and clicking "Reply" which should activate their own Reply UI.

syndication links in-stream

Since readers such as Monocle display u-syndication links on items, it is worth adding them to in-stream h-entrys.

Perhaps something like:

... 11:40 on 2014-06-29. Also on: t fb fl ig gh

Where the lowercase text abbreviations link to their respective silo syndication links (if any).

Perhaps with icons instead of lowercase text abbreviations.

This may require loading both bim and bim_s storage files to construct the composite stream of the homepage.

This would also enable "webaction buttons in-stream", since the fallbacks for those webaction buttons require the silo syndication links.

webaction buttons in-stream

In short two things:

  1. update look of web action buttons to be more Instagram-like
  2. web action buttons on notes/articles in-stream (home page) / collection (day and new month archives)
    1. screenshot existing stream presentation (desktop, mobile) and post as example on composite_stream#IndieWeb_Examples
    2. implement web action buttons on notes/articles in-stream
    3. screenshot new stream presentation (desktop, mobile) and post as example on composite_stream#IndieWeb_Examples

Update look:

I want to add web action buttons like Instagram has - I really like their grey boxy buttons with both icon and text, so something similar, e.g. in-stream text mockup:

... 11:40 on 2014-06-29. Also on: t fb fl ig gh [ ♥ Like ] [ ♺ Repost ] [ ↩ Reply ]

I find that Instagram's usage of boxy grey backgrounded buttons also serves as a nice visual separator between posts there, so I'm hoping to get a similar effect with a line of such buttons under my posts on my stream.

And update the citation UI on permalinks as well to be consistent. Text mockup:

... 11:40 on 2014-06-29 (ttk.me t4Wq1) using BBEdit URL: [ http: .... ] HTML: [ ... ] t View (Conversation) on Twitter [ ♥ Like ] [ ♺ Repost ] [ ↩ Reply ]

Note: these emoji are not visible on Linux (Fedora 20), nor Windows 7:

  • 🐓 rooster
  • 🐦 bird

And these are not visible on Linux (Fedora 20)

Atom feed past 24h

Change Atom feed to provide at least 1 entry and then past 24 hours of entries like what Malcolm Blaney does.

mobile friendly recent talks box

Recent talks (as a form of recent videos) on my home page!

I want a box on my home page that shows the recent n (maybe in a grid?) talks that I've posted/embedded.

For mobile perhaps a simple row of only 3 square cropped/shaped videos, similar to the sizing in Instagram's profile view.

For desktop (taller displays), perhaps a a 3x3 grid.

I'd prefer this show only talks I've given.

  • Fallback / first attempt - I'd be ok with showing all auto-embedded videos from notes.

Clicking on any video would go to the specific post.

Clicking on the "Recent talks" heading should go to a talks-only stream view, similar to ThisIsMyJam's one video full(ish) width view.

And then have that link to:

mobile friendly talks only stream

I want a separate page on my site

  • maybe "/talks"

that looks

  • at least as beautiful as Instagram or Tumblr for browsing through recent videos on mobile
  • at least as beautiful as thisismyjam.com for browsing on desktop

Even if all I'm doing is PESOSing from IG/YouTube or manually posting notes that happen to hot-embed videos from IG/YouTube.

Why: I think showing such a page will start to demonstrate the power of owning your own design on the indieweb - and how we make things just as beautiful as any app/silo.

And I know for one thing at least my parents will use it, or anyone wanting to catch up on my talks.


  • Autoplay next: when a video is finished playing, scroll to the next one into view (or just swap it in), and start playing it, kind of like an automatic play list.
  • webaction buttons that let them "like" or comment on the video on YouTube

While such silo specific webactions are not ideal - it provides at least:

  • some interaction/UX
  • visual cues that help the scrolling list of photos "feel" as nice as an Instagram stream of video posts


There is some support in Falcon for displaying some date based archive pages but they need more work.

archive pages

Need to add:

  • next/prev navigation buttons on all archive pages
    • day archives - have next/prev buttons as of 2018-308 - and now need:
      • show all entries for whole days on home page
      • link from home stream to the day previous-to-last-entry shown on home page stream, to implement simple pagination from home stream to previous posts
      • skip days without posts
    • similar to existing permalink page next/prev links with rel=next/prev
    • action: navigates to next/prev of same granularity
      • v0: even if empty archive page
      • v1?: skip empty archive pages
    • newmonth next/prev nav
    • bim next/prev nav
  • need better CSS for pages of all posts from a particular

archive navigation

  • need archive navigation UI for navigation across and into/out of archive pages.
  • better than just a big list of years/months links that are all too common on blogs
  • consider including on this day as another navigation axis
  • calendar grid view of posts by published date (like old Flickr used to, looking for their mid to late 2000s URL structure for this), tagged date (e.g. #2018_231, akin to Flickr's date-taken)
  • maybe "this week last year" (showing 3 days before and after? next 6 days?)
  • related:

day range

  • Use-case: "Previous posts" link from home page
  • Build: Dynamic archive pages base on day ranges in the URL
    • design day range in the URL - see aaronparecki.com home page pagination as an example
  • Minimum viable alternative: fragment to next previous post, in whichever newmonth archive its in
    • allows re-using existing newmonth archive pages
    • needs addition of fragment ids for each post in newmonth archives

archive templates

Gregorian month

Gregorian month archive pages for:

  • archive URL sharing / reference with other more familiar with Gregorian months
  • possible user 2 - expected default archive month view preference

Unix 3D archive views

Just because. Using something like:

"It's a Unix system! I know this!" @beclamide July 15, 2019

Jurassic park Unix 3D file navigation animation

(SGI description)


Where posts are files in the diagram, and days / months / years are directories.

improve like posts

While they're still fresh in my mind, improve like posts:

  • style differently than notes when in-stream, e.g. home stream
    • add like-post to existing class="h-entry" for each like
    • style .like-post to a smaller font, similar to current small grey text date-time, to clearly distinguish it in a stream from adjacent notes.
  • cluster sequential likes of the same person's stuff even more[9]
    • common use-case for me: reading individual people's profiles / sites serially post by post, and often liking a bunch of them in a row. I find reading people like that much more satisfying / calm than any kind of random aggregate "news feed" of updates from all the random sources.
  • blog about like posts:
    • researching notifications for design ideas
    • quick bit on notification-first design (what, why, that answers the tweet replies to my notes about it)
      • separate blog post
    • like#Brainstorming - how I went about it, the steps
    • storage
    • deployment

mobile home template header icons folders

Implement mobile home template header icons folders per Toward A People Focused Mobile Communication Experience: What Next

  • Prototype HTML+CSS+JS for mobile home template header icons folders
    • in a separate standalone minimal home.html - as simple re-usable code (should be easier to create and understand/maintain)
    • Use JS to output inline markup for links to comm protocols that are spammed (e.g. email-ID in facetime: )
    • Consolidate photo and h-card with description at top, followed by Contacts, Create & Meet, Elsewhere links, styled minimally
  • Deploy on personal site by incorporating home.html into live index.html markup
  • Prototype for iOS7 for limited/focused testing on iPod/iPhone and user feedback
  • Generalize to work for FirefoxOS device which should then work well on Firefox for Android (and Android in general).


Contact expanded

When a viewer taps the Contact icon folder it expands as follows, and then the viewer can tap the mode of messaging/communicating they want to use to contact me which immediately opens a new message (txt, FB Messenger, G+ Hangouts, AIM IM), or starts a new call (FaceTime, Skype), or Twitter new direct message window. Directly to communicating - bypassing all comm app home page / activity distractors.

The one change I'd make from these mockups are some of the labels. All of the labels should be verbs, not nouns, indicating the action the user wants to take and thus reinforcing their intention.

E.g. "Messages" should be "txt message", "Messenger" should be "FB message", "Hangouts" should be "GTalk", and the rest seem to read fine as verbs.

iOS6 mockups

Original prototypes done in iOS6, probably not worth implementing, but may contain interesting UI ideas nonetheless:

Contact expanded

The one change I'd make from these mockups are some of the labels. All of the labels should be verbs, not nouns, indicating the action the user wants to take and thus reinforcing their intention.

E.g. "Messages" should be "txt message", "Messenger" should be "FB message", "Hangouts" should be "GTalk", and the rest seem to read fine as verbs.

auto POSSE photos to Flickr

Improvements for auto POSSEing photos and videos to Flickr.

Improvements: (make this into a separate lower priority itch / working-on)

Either / both of these would be nice improvements over the current auto_tag hack in Falcon:

Future alternative: (make this into a separate lower priority itch / working-on)

I could also try adding native Flickr POSSE support to Falcon using Jeremy Keith's code:

POSSE responses to Tumblr posts

I've setup http://tantek-com.tumblr.com/ purely as a POSSE bridge for propagating my like, repost (TBI), and reply posts to Tumblr posts, directly into Tumblr so that the comments section on the Tumblr post says stuff like:

  • tantek.com likes this
  • tantek.com reblogged this from someoneTumblrUsername

Ideally I'd like to automatically do so, e.g. via Bridgy Publish (open github issue).

Similar work: silo.pub

  • Might be able to re-use some of the open source: https://github.com/kylewm/feverdream to automatically post responses to Tumblr posts to Tumblr.
    • As of 2015-07-30: "can't actually publish native likes/reposts/etc. through silo.pub right now... even if you u-like-of a tumblr post, it still publishes a note with mf2 markup in it"[10]

But until I get one of those approaches working automatically, I'll have to manually POSSE my responses to Tumblr posts into Tumblr.

Add to Google Calendar

Deprioritizing this in deference to filing bugs about Google Calendar's ICS failures, e.g. the Android app, when alternatives like the Samsung Android calendar app handles my "Add to Calendar" ICS from H2VX just fine.

Implement "Add to Google Calendar" links like Marty has

  • On event POSSE tweets
    • 🗓 Add to GCal: Google Calendar link (redesign that text as necessary)
    • add falconpost.php POSSE code to generate that link


Beyond that, I find my prioritization changes often enough that I just keep a loose collection of thoughts/ideas/wants/brainstorms that I occasionally iterate on until something reaches the point of - hey, I could finish coding that in a day or two.


Itches are other things I want on my site but haven't started implementing yet. They are a collection of annoyances that have respective features / improvements. As their annoyance level bubbles to the top, they're likely to become concrete "Working On" tasks.


I need delegation on my site, so I can let a few trusted folks post on my behalf while I’m on vacation, e.g. indie events for Homebrew Website Club meetups. per http://tantek.com/2018/019/t2/need-implement-delegation

Geo-tagged Notes

I want my notes to optionally (opt-out?) have geo-tagging added to them in my (POSSE) posting UI.


1. This is primarily a building block for checkin posts.

2. 2014-322 noted that @TwitterData presentation showed lots of presentation where they showed aggregated maps and animated maps based on geo-tagged tweets. This is interesting micro-incentive to geo-tag your notes - by geo-tagging your notes, you get to participate in such data aggregations.

I'm thinking something very simple to start with (potential improvements noted inline)

  1. Get and show current location in post UI. Upon load, have my /Falcon UI get current location and show it
    • Minimum zero user effort: Use Geolocation API to get data automatically
      • display lat/long/altitude text
    • Better: Map. display a map centered on current location
      • with a blue dot for current location
    • Better: dynamically updated so it works while moving / traveling (e.g. in train or card), or upon wake from sleep
    • Even better: scrollable map
    • Even better: movable pointer / blue-dot so I can "fix" the location
    • Alternatively: a text field to do location search and get a lat long accordingly
  2. Submit lat, long info to server
  3. Add location to POSSE tweet copy when I click "Post"
  4. Server attach lat, long to post storage along with POSSE tweet ID
    • inside the "h-entry", add "p-location h-geo" with "p-latitude" "p-longitude" properties to store lat long

Expiring Content

Main article: expiring content
  • figure out how to author/store expiring content in Falcon storage
  • figure out how to best render/display expiring content
  • implement and test with a post that forward references things which are expected to become less relevant at some point in the future.

PESOS Nike Running

As a stopgap I'd like to PESOS my Nike+ runs.


Indie Venues and Checkins

Itch: Async / offline checkins.

  • Scratch: some cache of recent common locations to pick from even when offline, and the create post while offline.

Itch: Existing venue reference URLs are all broken (for an H&M store, the hm.com store locator) or bloated with unnecessary Javascript (Yelp, Foursquare).

Itch: really getting tired of venue griefers/abusers/overmergers on Foursquare. Overmergers: people who take two distinct venues and merge them into one because they have some mistaken idea of what a "venue" is. Overmerging ends up redirect both previous unique URLs to one of them, and it effectively destroys your history at checking into either, because after that, you don't know which it was. It's like wiki vandalism but worse because there is no history and no accountability.

  • Scratch: Indieweb checkins from/on my own site, which then POSSE out to Foursquare (required for me because I'm a heavy Foursquare user and I wouldn't switch over to using my own indieweb checkins without that automatic capability. Mobile web support via Geolocation API is a must.)
  • Scratch: Indieweb venues are essential to make indieweb checkins work and maintain data fidelity. ** Challenge: how to deal with POSSE'd venue references when silo venues are subject to such vandalism as noted in the itch description.

More thoughts on what I want for indieweb checkins on my site:

Levels of access

Four levels of privacy/access that I personally want / have use for.

  1. myself only. use-case: personal/private logging.
  2. passive friend access (i.e. they can see when they're logged into my site, "current location:", but I'm not broadcasting to them on silos). use-case: ok with friends knowing where I am, but it's not important enough to broadcast to them (reduce unnecessary interruptions to my friends).
  3. broadcast to friends only (i.e. POSSE out to Foursquare). use-case: I'm somewhere where I wouldn't mind if friends in the area happened to be informed in real time and show up.
  4. public checkin posts. use-case: public events where there's many more people than just my friends, and I'm ok with anyone knowing that I'm there (e.g. I'm speaking at or attending a conference).

Past discussion sessions

I've led some discussion sessions on this topic and we took notes on what we figured out:

Key checkin realizations

  • a checkin may just be a note with venue information (and nothing else, maybe text fallback like "at venuename")
  • a checkin with shout may just be a text note with venue information
  • a checkin with photo and shout may just be a note with a photo and venue information
  • Thus the key to implementing checkins is just:
    • figure out how to attach venue information to posts and notes in particular
      • i.e. what to add to h-entry, would a class="p-location h-card" be enough to imply at venue when posting?
    • figure out how to present notes that are checkins as implied by the presence of venue info:
      • only have venue information (with possible text fallback)
      • have an explicit text note with venue information (again with possible text fallback)
      • have a photo (optional text note) with venue information (again with possible text fallback)

I've been abstracting what we've figured out so far into these pages, but much of what was discussed in those sessions has not quite made it into them:

More help/input/contributions/edits welcome!

client side search

Google search results have been very poor for my posts starting sometime in 2013 to the present (2016).
Though I’ve replaced Google search results with DuckDuckGo non-date-ordered site-search results (at IndieWebCamp LA 2016), and they’re better than Google’s non-date-ordered site-search, they still need improving:

  • Requires visible "site:tantek.com" in the search box which is both visually noisy, and prone to error (reader altering it), especially on mobile where the search box is smaller and tapping on it and typing will likely alter it.
  • Want date-ordered results
  • Want permalink-only results (not storage files or home page)

Thus I am itching to build search into my own site.

I'm thinking of jumping directly to search level 5 (and thus defining it) with fast client side search using lunr.js.

See: search#client_side_search for details, but in short:

  • After someone loads tantek.com or a post permalink
  • At idletime, check to see if there is a client-side search index, if not
    • Setup websocket to receive notification of site updates, perhaps as part of:
      • Itch: real time home page stream updates
      • Itch: real time post permalink updates (e.g. edits)
    • XHR most recent bim
    • Parse it into structure post name, entry, author etc.
      • requires updating Falcon storage reading code from PHP to CASSIS
    • Build index using lunr.js
  • When receive site notification update, re-XHR/parse/index most recent bim (or just permalinks since last index)
  • Enhance existing search box with JS to handle search fully clientside:
    • When users uses search box on my site:
    • Check to see if search index exists, if not
      • XHR most recent bim, parse it into structure post name, entry, author etc., index with lunr.js
    • Perform query and get results
    • If no results, XHR/parse/index previous bim and try again
    • Display results by date order, for a specific date range
      • requires URL design for date range results page
      • requires building HTML+CSS of a results page for a date range
      • navigation to next/previous results
    • Upon navigation to previous results, XHR/parse/index previous bim as needed just in time
    • Keep all indexes in local client so paging back/forth in results is fast (no IO requirement)

linked hashtags

hashtags in my notes are currently unlinked because

  • I don't have a good/simple hashtag detector (see hashtags#Regex for current thinking)
  • I don't know where to link them to (no good indieweb tag aggregators yet), and
  • I don't have a tag based destination on my own site


  • implement hashtags#Regex for at least #hashtag auto-markup (e.g. for propagating tags via Bridgy Publish to Flickr etc.)
  • figure out a local destination for hashtags, e.g. tag search (AKA "tag results", "tag feeds"), paginated by date
  • update CASSIS auto_link function to link to those destinations automatically


Having updated and/or deleted a few notes and had to go do so manually on Twitter, I'd really rather have it be more automatic from my site and thus I'd like to implement:

In addition, the UI and code flow for editing/saving (updates), and deletes will help me better understand requirements for the more functional indie wiki pages (as described below).

Accept Webmentions Directly

Write a webmention handler endpoint and support accepting, handling, storing webmentions in addition to displaying them.

Switching rel=webmention handler from webmention.io to direct handler on site.

Private Groups

Not high on my priority list (though would be necessary to figure out to extract myself from FB).

Use-case: I've made use of private groups a bunch on Facebook in the past year. So I see their value.

I am not sure how the indieweb equivalent would work but I think something like this:

I want to be able to from my own site make a private group work for indieweb folks:

  • Create a private group hosted on my domain (secondary: on an external custom group-specific domain)
  • Add people to it (by domain name)
  • or maybe just Invite people to join it
  • Post to it such that only those in the group can see it (expectation, future members could see it too)

I want to be able to from my own site interact with a silo private group:

  • Watch (reading) posts and other activity on a private group on a silo like a Facebook group.
  • Publish (privately? to my personal site mirror of the private group?)
    • Posts / notes to the private group, and POSSE to the silo private group
    • Replies to posts in the group and POSSE to the silo private group
    • Like posts in the group and POSSE to the silo private group
  • Receive notifications on my homepage of:
    • Mentions of my name in posts or comments in the silo private group
    • Likes in the silo private group of my comments or posts that were POSSEd to the silo private group
    • Comments in the silo private group of my comments or posts that were POSSEd to the silo private group
  • UI for responding to such notifications by creating a reply or liking or writing a new post as described in Publish

Own My Listens

I want to / need to own my listen/scrobble posts on my own site.


  • last.fm recently (2015-08-07) launched a new version with drastically fewer features (e.g. ability to play music has been completely delegated to pay service Spotify


  • Likely PESOS for now from last.fm
  • Backfill with a last.fm export and import into my site
  • Perhaps PESOS Shazam listens from @t_silos
  • post from iPod listens to my own site
  • post from iTunes/Mac listens to my own site
  • POSSE from my site to last.fm

POSSE tweet photo Twitter API

Consider implement Twitter#POSSE_note_with_photos_to_Twitter:

  • directly using Twitter API, and my existing tweet POSSE code

improve photo plain text title name

Finished 2016-080:

  • create a new CASSIS function that creates a (better) plain text equivalent for photo (and video) posts
  • minimum: drop leading URLs from the start of a post that would not result in visible text content after an auto_link


  • Feed readers. Numerous folks have provided critical feedback that my photo posts have bad names/titles when shown in feed readers, due to the URLs of the photo (and subsequent URL of what it should link to) showing up in the plain text view which is used in entry title in the Atom feed.
  • Facebook link preview. Also the link-preview of my photo posts on Facebook shows the URLs at the start of the post as text underneath the photo, which for long CDN jpg or mp4 URLs, fills the entirety of the text below the link-preview image.

Both of these are together caused a sufficiently strong itch to fix ASAP.


  • consider show [photo] instead of photo URLs (and their fallbacks), and [video] instead of video URLs (and their fallbacks)
    • unsure if this synthetic summary text is helpful, or noise
    • counter-use-case: Firefox tab names show the first part of the page , thus better to avoid anything generic at the start of a post name

Implementation Design

Code Files

Falcon consists of PHP code (some of which is CASSIS) to display posts and code to write/publish/syndicate posts. Falcon code consists of only three files (bolded), some additions to the root .htaccess, and the libraries cassis, relmeauth.php, and tmhOAuth in the following structure:

URL routing and display: (live at http://tantek.com/ )

  • cassis.js
  • falcon.php
  • index.php
  • whistle.php (see Whistle)
  • .htaccess - only a section therein

write/publish/syndicate: (live at http://tantek.com/falcon/ )

Note: as I cleanup, refine, and rewrite useful functions in Falcon in CASSIS, I've been open sourcing them in cassis.js. The following building block functions have been incorporated into other projects:

  • ellipsize_to_word() - particularly useful for POSSEing out to Twitter
  • auto_link() - better plain text autolinker (and embedder) than Twitter, Facebook.

- Tantek

Also using Discovery in PHP approach to find webmention endpoints then curl to send.

  • in particular do a HEAD request first, then GET if no endpoints found and type is text/html or application/xhtml+xml.
    • Why?
      • simplest way to both minimize bytes requested by my server and avoid GETting non-HTML links (which I do link to plenty often in my posts)
  • if no webmention endpoints found, do fallback discovery for pingback inside same HEAD/GET results and send pingback, using an approach like https://gist.github.com/aaronpk/5744879
    • Why?
      • To support posting comments on indieweb community member's sites that receive pingbacks but not webmentions, e.g. Laurent's Testing #indieweb federation.


Falcon currently only uses templates for the home page and feed. The rest of the output markup is hardcoded in falcon.php (Note: that's not good design, all output markup should be in template files. There should be no markup in the implementation code itself.).

falcon.php looks in the same directory for:

  • index.html - to construct a home page with the most recent N (default: 20) posts.
    • .stream - the most recent posts are placed into an ordered list element (
        ) which is then appended as the last child of the first element with class name of "stream" in the index.html template.
    • updates.atom - to construct a home feed with the most recent N (default: 20) posts.
      • feed "meta" elements as well as a series of elements representing the most recent posts are appended as the last child(ren) of the last element of the template (which happens to be the element - not a very flexible design - then again, neither is Atom itself :P ).

    Storage format

    When displaying the most recent N posts, Falcon looks for YYYY/B.html files in the current directory (YYYY being the current year and B being the current bim) and earlier files as necessary to retrieve N posts or until a previous storage file is not found, whichever comes first.

    When displaying a post permalink or archive for a particular year, bim, month, or day, Falcon computes the paths to the necessary file(s) according to year and bim and reads them.

    Each bim storage file is treated as XML-Valid HTML5 hAtom and PHP DOMDocument & DOMXPath is used to retrieve all .hentry elements in document order inside the first .hfeed element. The .hentry elements are ordered most recently published first.

    For each such hentry, the first (in document order) instance of each of the following is retrieved (also using XPath) from the hentry's descendants:

    • .published - element parsed per the Value Class Pattern: Date and time values
      • In addition, date is implied from post permalink if only published time is provided
    • .entry-title - element parsed for both plain text and nested markup
    • .entry-content - element parsed for both plain text and nested markup
    • .using - element parsed for plain text
    • .uid - element parsed for its href attribute if on an A tag, else contents. Treated semantically as permalink for the hentry.
      • backward compat: if no .uid element, then
        • [rel~=bookmark] - element parsed for its href attribute
    • .u-like-of - element parsed for its href attribute if on an A tag, else contents

    All instances of each of the following is retrieved (also using XPath)

    • .u-in-reply-to - elements parsed for href attribute if on an A tag, else contents
    • .u-syndication - elements parsed for href attribute

    All "parsed for plain text" instances trim leading/trailing whitespace but preserve all other whitespace both for note permalink presentation, and for POSSEing notes to Twitter.

    • .p-x-style - elements parsed for their text which is presumed to be a CSS style sheet that can be rendered as is inside both a top level element, and inside an element as the first child inside an h-entry.

    Every time an "hentry" is published & syndicated to a 3rd party service (POSSE style of course), falconpost.php appends a child element to the end of the "hentry" with:

    • class="url u-syndication"
    • rel="syndication"
    • href={absolute URL to syndicated copy on another service}
    • innertext - perhaps name of service and service-specific unique post identifier
    http://twitter.com/t/status/314548524266172416">Twitter post 314548524266172416

    Such syndication references are also read by falconpost.php to see which entries have been syndicated to which service(s) (only Twitter is automatically supported currently) when determining which entry to syndicate to which service next.

    In addition, falconpost.php stores in-reply-to information for reply notes by appending a child element to the end of the "hentry" with:

    • class="u-in-reply-to"
    • rel="in-reply-to"
    • href={absolute URL to original post being replied to}
    • innertext - "In reply to: " and perhaps name of service and service-specific unique post identifier
    http://twitter.com/_/status/330099833383833601">In reply to: 330099833383833601


    Home page

    Home page is routed by .htaccess directive to index.php for handling:

    DirectoryIndex index.php index.html

    index.php then simply includes falcon.php for handling.


    Shortlinks are routed by .htaccess directives to whistle.php for handling:

    RewriteRule ^b/[0-9A-Z_a-z]{3,5}.?$ whistle.php
    RewriteRule ^e/[0-9A-Z_a-z]{3,5}.?$ whistle.php
    RewriteRule ^t[0-9A-Z_a-z]{3,5}.?$ whistle.php

    Note that each post type's shortlink character code is handled by a separate rule. This is deliberate design flexibility so that each post type can potentially use a different algorithmic short URL.

    Permalinks and archives

    Any path that starts with a four digit number then a slash then 1-3 digits is presumed to be a year YYYY and the start of a permalink (/YYYY/DDD/tN/) or an archive page (/YYYY/DDD/t, /YYYY/DDD, /YYYY/MM, /YYYY/B) where:

    • "DDD" is ordinal day of the year
    • "t" is one character post type (per Whistle design)
    • "N" is decimal number nth post of that type that day
    • "MM" is for "new month" (per newcal new months)
    • "B" is for bim number

    Permalinks and archive pages are routed by .htaccess directives to falcon.php for handling:

    RewriteRule ^\d{4}/\d{1,3} falcon.php

    Legacy feed

    Legacy feed requests are routed by .htaccess directives to falcon.php for handling, e.g.:

    RewriteRule ^updates\.atom falcon.php

    Completed Tasks

    Archiving completed tasks here when they are non-trivial and especially when they require various bug fixes / improvements to Falcon accordingly.

    Migrate to new web host

    Completed 2019-03-04! Summary improvements:

    • protocol relative links in various places

    I need to migrate to a new webhost by 2019-03-06. Existing host is literally shutting down.

    • figure out what set of webhosts to research
      • Chose DreamHost - lots of friends/colleagues use them and they like it
      • Bluehost - recommended by my current host as a place to migrate to
      • Reclaim Hosting - folks in IndieWeb community have great experiences with them.
        • Supposedly $30/year with ssh access.
        • storage: $30/y for 2GB? $50/y for 10GB?
      • others?
    • what questions to ask of each host?
      • automatic and free HTTPS? (if I'm switching hosts, this is a requirement in 2019)
        • yes
      • ssh access? I depend on scp for my current workflow
        • yes DreamHost
      • Apache or equivalent support? (I depend on .htaccess files)
        • yes DreamHost
      • storage levels?
        • unlimited(?) DreamHost
      • bandwidth?
        • unlimited(?) DreamHost
      • automatic OS and web server software updates? - I have zero interest in maintaining these
        • yes
      • automatic PHP updates? - I depend on PHP and don't care to bother with updating. I deliberately write minimally dependent PHP (mostly in CASSIS) that I want to require it (my code) to work forward/backward compatibly with any version of PHP 5.2+
        • yes / opt-in auto-update PHP DreamHost
      • unlimited email aliases / forwarders? I have dozens (100+?) of email addresses on my domain that I need to have aliases/forwarders for
        • yes DreamHost
        • a format for importing/exporting list of email aliases? so I don't have to enter/create them all by hand (but I can if I have to :/)
          • simple text file one line per alias mapping - DreamHost
      • ...
    • choose a web host and document methodology / reasoning why
    • migrate and document steps necessary
      • figure out what files/dirs of my site I can redirect to Internet Archive instead of maintaining, copying over
        • none for now. rsync made it easy to maintain all files as-is.
      • figure out what minimum files/dirs I need to copy over and how to most efficiently do so
        • /log
        • /YYYY - YYYY = 2010…2019
        • postponed: rsync all files instead
    • flip DNS switches and hopefully it all works!
      • first test it at a subdomain of another domain - worked in general
      • fixed a bunch of protocol-specific links (http:) to be protocol relative, start with "//"
      • flip DNS for tantek.com.

    Dropped Features

    POSSE RSVP video photo to FB

    Before 2018-08-01, Falcon supported some POSSEing to Facebook:

    • RSVP posts were automatically POSSEd to Facebook to RSVP to FB events, using Bridgy Publish (since 2015-145)
    • photos were automatically POSSEd to Facebook using Bridgy Publish (since 2015-312)
    • Video: automatic POSSE to Facebook
    • Event summary as text indirectly to Facebook from POSSE Tweet
    • Facebook: RSVP to Facebook events, photos, and notes*
      • *notes are POSSEd to Facebook indirectly via Twitter to Facebook bridge, per same limitations as POSSEing notes to Twitter.
      • Occasionally longer notes wer manually POSSEd directly in their entirety from tantek.com to Facebook using Bridgy Publish, and then the Falcon original is manually edited to link to the Facebook POSSE copy. Falcon then automatically displays the syndication link to the Facebook POSSE copy on the Falcon post permalink.

    Backfed RSVP from FB

    From mid 2017 until 2018-08-01, Falcon supported some backfeed from Facebook:

    Canceled Features

    auto Bridgy POSSE to FB

    2010-08-01 Bridgy shutdown POSSE to FB due to FB posting API shutdown.

    Re-evaluate if/when FB re-enables posting via an API (maybe Data Transfer Project import?), and if Bridgy is amenable to adding support for the (new) API.

    Rather than manually using the publish form at https://www.brid.gy/facebook/214611#publishes,

    For all:

    that I post on my own site,
    when clicking the "Publish" or "Tweet it" button (which should be renamed, "PuSH and POSSE it" maybe?) :

    1. if there is no u-syndication link to FB on the post, display a
      link instead (so Bridgy sees that)
    2. send a webmention to Bridgy publish like:
      curl https://www.brid.gy/publish/webmention -i -d "source=http://tantek.com/2014/210/t1/trackattack-warmup-laps-first-time-did-all&target=brid.gy/publish/facebook"
      (need https and www to avoid redirect, which won't POST)
    3. parse the results of the curl, e.g. something like
      "url": "http://facebook.com/456_789",
      "type": "post",
      "id": "456_789"
    4. save the [URL] in a u-syndication hyperlink in storage on the post with the link text "Facebook post [id]", *after* the Twitter syndication link

    Then anytime I "PuSH and POSSE" an article, note, or a reply/like of a FB post, a copy should automatically show up in my FB timeline.

    Once confirmed that this works:

    1. go to Twitter preferences for @t
    2. turn off cross-posting to FB
    3. edit the Falcon#POSSE_Details description above to note POSSEing to FB via Bridgy (instead of via Twitter)
    4. edit the POSSE IndieWeb Examples to note POSSEing to FB via Bridgy (instead of via Twitter)
    5. edit Facebook#POSSE_out_to to move tantek.com from "from Twitter " to "Bridgy" subsection

    indie comms Hello button

    Figure out and setup support for Mozilla Hello WebRTC client in my indie comms solution on /contact

    More references:

    The Falcon logo is a Glider from Conway's Game of Life in a phase that resembles a falcon flying with its wings up and outstretched, and feet down and slightly back swooping downward to pick something up, e.g. a post from the author to go deliver to their indieweb site and syndicate out to other destinations as well.


    See Also