-
Notifications
You must be signed in to change notification settings - Fork 8
Advanced Functionality
This page documents advanced functionality of the card-web app that is not immediately obvious, or only visible to admins or editors.
For basic features that all users can use, see https://medium.com/@komorama/how-to-use-thecompendium-cards-ee8660b16b11
Hit the magnifying glass below any card to search for a card. It's a powerful search engine that will also match cards that only partially match the query.
When you're editing a card and have selected some text, if you hit Cmd-K, instead of showing a normal dialog to ask for the URL to point to, it pops open a search dialog box to find the card you want to link to. Just select the thumbnail of the card you want to link to.
If you don't see any existing cards, you can click the plus button at the bottom of that dialog and it will automatically create a new stub card and link to it with that title. This is a great way to stub out ideas you want to develop more, since new cards are unpublished by default, so only you will see that there's even a link there.
If you want to link something other than a card (e.g. a normal external link), then hit the link button in the bottom right up the dialog that shows up.
Any time that there's a link, tag, or thumbnail representing another card, if you hover over it and pause a preview window will show up.
Cards can have images in them. To add an image, open a card for editing, then go to the Content tab in the editor panel and in the images section choose to add an image.
You can paste in a URL to use directly (it should be a full URL like https://example.com/path/to/image.png
or you can upload a file from your computer.
Once an image is added, you can click the chip for it to open up image properties, including alignment, swapping out for a different image, changing its margin, and its size.
The web app has an advanced TODO functionality. It keeps track of TODOs that the author of a card might want to do. There are many different types of auto TODOs (enumerated below). These TODOs show up as red tags beneath the card for users who have edit access on it. The auto TODOs are set automatically when some condition is met, for example the 'Inbound Links' auto TODO is set for any card that does not yet have other cards that link to it. But sometimes you want to ignore a TODO, or turn it on even when it normally wouldn't be. When editing a card, you can add a Force Enable or Force Disable for any TODO.
TODOs all have filters (see below on URLs and Filters), making it easy to find cards that have a certain type of TODO. Any card that has any TODO will also match the has-todo
filter. Thus, the URL /c/has-todo/
is a great way to see cards of yours that still need things to be done on them.
- slug - Applies for cards that do not yet have a slug (that is, their default url show their ID instead of a human-readable name)
- content - Applies for cards that have zero characters of content in their body
- substantive-content - Applies for cards that have only a trivial amount of content in their body
- links - Applies for cards that do not link out to any other cards
- inbound-links - Applies for cards that do not yet have any other cards that link to them
- reciprocal-links - Applies for cards where there is at least one inbound link to them that does not have a matching outbound link. If you want to ignore that link, x it out in the "Missing Reciprocal Links" section of the editor
- tags - Applies for cards that don't yet have any tags applied.
- published - Applies for cards that are not yet published
- freeform-todo - Applies for cards that have any text in their Freeform TODO text field
The web app has a powerful filter/sort system that can be accessed via modifying URLs. There currently aren't many affordances in the app to modify them.
The back button should work; if you want to go back to a card you were recently looking at, you can hit the back button.
The URL is constructed like so:
-
c
- For the card viewer - The default set of cards to show. This is almost always
all
, so it's canonically elided. If you view a reading list, that's actually a special set, instead ofall
- Zero or more filters, separated by
/
. The final collection of cards is the intersection of all filters -
Optional a sort, like so
sort/<sort-name>/[reverse]
- The card name, slug, or ID
Every link links to a specific card in the context of a certain filtered/sorted set of cards. When users navigate around the webapp and click links to other cards, the URL keeps the same filters and sort, unless the selected card isn't in that collection, in which case it updates the URL to the card's default collection.
If you omit a card ID, then the URL will select the first card that matches that collection: /c/starred/
will link to the user's collection of starred cards.
Mostly you'll want to add filters. There is a long, long list of available filters (see the section below that enumerates them).
When you chain filters together, it's the intersection of them: /c/has-substantive-content/unpublished/
for example would select the set of cards that have non-trivial content, but are not yet published.
However, it's also possible to union multiple filters together by delimiting them with a +
: /c/starred+read/has-comments/
would select all cards that have a star or a read by the current user, AND have comments. The filters that are unions are basically treated as though they are a single filter that combines all of the items in any of the filters they are made of; they are then intersected with any later filters.
There are some URLs (e.g. complex filters) that don't have any affordance in the UI. You can modify the URL directly and hit enter in the browser's URL bar, but that leads to a full refresh of the app, which can be slow. You can type Ctrl-Shift-L to pop a dialog that allows you to modify the current location and navigate within the app without a full refresh.
When editing cards, you can edit the body text in the field marked body, or you can edit the text live on the card. Editing it live on the card is the preferred way because there are fewer bugs. You can use keyboard shortcuts:
- Ctrl-B : Bold
- Ctrl-K : link selected text to non-card link
- Ctrl-Shift-K : find a card to link to (see below section)
- Ctrl-I: italics
- Ctrl-7: bullets
- Ctrl-8: numbered list
Note that the body editing via content editable has a number of known issues.
In the card info panel, it prints out cards that link to this one. Cards that link to this one, but where this card does not yet link back to it, are shown in bold.
The web-app will automatically suggest tags and similar cards for editors. While you're editing, you'll see a 'Similar Cards' list in the card-info panel to the right, and a 'Suggested Tags' in the editor itself. The similar cards list skips links and inbound_links for the card. The suggested tags skips tags that are already on the card. The overlap detection is done via looking for the most distinctive words on cards and seeing how they overlap with the current card.
Cards by default are only visible to their creator. It is not until they are published that they are visible to others who have view privileges for the app. For users who can view them, unpublished cards show up as gray cards, and links to them show up as red. For users who cannot view them, the app pretends they don't exist (their data is literally not downloaded to the client), and links to them render as though there is no link.
When you're ready for a card to be visible to other viewers, hit the publish button.
Each card has a single id, which is set at creation time and never changes. The card's id is the foolproof way to find the card; it is how cards link to other cards, among other things. But the id is often a string like c-123-abcdef
, which is not pretty or memorable. For that reason, cards can also have 0 or more slugs
, which are prettier strings like complex-vs-complicated
. A slug once added can never be removed (since external links might point to it). A card can be navigated to by using its id or any of its slugs. A card also has a name, which is the default identifier to show for it. Typically this name is the first slug set. The name is what will canonically be shown in the URL when the card is being viewed.
When editing a card, you can hit the '+' button next to the card id or slug to add a new one. The text next to that button is a (hidden) drop down, allowing you to switch to any of the identifiers. When you add a new slug, the webapp defaults to setting it to be the card's name.
Every card exists in the context of a single section. A section is a named ordered list of cards, and includes an ordinal so it can be sorted compared to other sections. The default set of cards is known as all
and contains the concatenation of all cards in each section, with each section sorted by their ordinal. Thus, the order of cards within their parent section is important for the default ordering of the cards whenever they are shown. Other collection features will filter cards out of the main collection, or in some cases override the default order to sort them in a new order.
It is possible to have cards that are part of no section. These cards are known as orphans and they don't show up by default in any collection, and are only visible when they are navigated to directly.
Tags are like sections, except that they are unordered. Instead, they merely contain the set of cards that are affiliated. Tags thus can be used as filters. Tags also display underneath a card and in the card info panel. When a user clicks on them, they'll be taken to the same card, but in the context of that collection
Cards of type 'concept' are cards the represent a concept. They have a title that defines the concept, a body describing a bit about the concept, and then automatic link sections showing cards that reference the concept. When saving a normal card, if it appears to mention a concept, an explicit concept reference (or an ACK reference) must be added.
If you're an admin, you can see which concepts the system thinks you might be missing. This calculation is very slow. You can enable it by expanding the info panel at the top of the card drawer and checking 'Show Missing Concepts'.
You can create a card by swapping the card_type of an existing card, or by selecting a card that wants to reference a concept card, and in the 'Select card to reference' dialog, hitting the 'Add' button. Once at least one concept card exists, you'll see it in a Concept tab at the top, and when viewing that tab you can add concept cards directly.
There are multiple sub-types of concept references:
-
concept
- The generic concept reference -
synonym
- For when the referred to concept could be used interchangeably with this concept and still make sense. See also title alternates, below. -
opposite-of
- For concepts that are in contrast to this concept. -
example-of
- For when a card of any type is an example or more specific type of a given concept
Concept cards are known canonically by their title, but also by any "title alternates". These title alternates can be modified by going to the Content -> Title Alternates field in the card editor. A concept card can also be referred to by any of its title alternates (multiple can be separated by commas). All of the various titles/title-alternates of concepts must be unique when normalized and stemmed. That is, things like 'Optimizing is Important' and 'Optimized importance' would be considered equivalent.
The web app supports a number of powerful filters and sorts, although this functionality isn't exposed in the UI; you have to know to modify the URL by hand. (See the URL section above about how to modify the URL).
Filters are unordered collections of cards. When applied to a collection, they remove any cards in the collection that aren't in their list. There are many, many filters. Many have a positive and negative version. Filters that are part of the general has-todo filter have needs- and does-not-need variants (see more on TODOs, above).
-
has-todo
/no-todo
- If the card has ANY todos active -
has-comments
/no-comments
-
orphaned
/not-orphaned
- Whether the card is part of a section or not. Note that the default set of cards explicitly only includes cards that are in a section, soc/orphaned/
will match no cards. To have some cards possibly match that filter, use the everything set, which includes literally everything:c/everything/orphaned/
-
has-notes
/no-notes
-
has-images
/no-images
-
has-slug
/no-slug
/needs-slug
/does-not-need-slug
-
has-content
/no-content
/needs-content
/does-not-need-content
- Whether the card has even a single character of body content -
has-substantive-content
/needs-substantive-content
/needs-substantive-content
/does-not-need-substantive-content
- Whether the card has more than a non-trivial amount of content -
has-links
/no-links
/needs-links
/does-not-need-links
- Whether the card links out to other cards -
has-inbound-links
/no-inbound-links
/needs-inbound-links
/does-not-need-inbound-links
- whether other cards link to this one -
has-all-reciprocal-links
/needs-reciprocal-links
/does-not-need-reciprocal-links
/needs-reciprocal-links
- Whether every inbound link to this card that is not listed as an override is matched with an outbound link -
has-tags
/no-tags
/needs-tags
/does-not-need-tags
-
published
/unpublished
/does-not-need-to-be-published
/needs-to-be-published
-
prioritized
/not-prioritized
- An auto TODO that only is applied manually for cards that the author wants to prioritize developing. -
mined-for-content
/not-mined-for-content
/does-not-need-to-be-mined-for-content
/needs-to-be-mined-for-content
- Working notes cards by default need to be 'mined for content' - that is, have their insights captured in normal content cards that reference back to them via amined-from
reference. This TODO captures that need. It will only ever turn off for working-notes cards if you manually disable the TODO. If you want to find cards that are partially mined, you can filter forhas-inbound-mined-from-references/not-mined
, which will return cards that have at least some mined-from references inbound, but haven't yet been affirmatively marked as fully mined. -
has-tweet
/no-tweet
-
has-freeform-todo
/does-not-have-freeform-todo
- Whether the Freeform TODO field on the card is empty
There are also filters for every card content-type:
content
/ not-content
/ section-head
/ not-section-head
/ working-notes
/ not-working-notes
There are also special multi-part filters, called configurable filters, which have multiple slashes in their name, e.g. updated/before/2020-3-20
The most common type of configurable filter is the query filter, which takes queries like query/hill+finding/
. Those queries will lead to the collection that's returned being sorted by how well they match the query, unless you append sort/original-order/
. The query should be encoded with spaces as +
, and any other non-url-safe characters encoded using encodeURIComponent
, which for example would expand /
to %2F
. If you want to only show cards that match all provided terms (in any order), use query-strict
as the filter name.
Another type is exclude
. It reverses whatever filter comes immediately after it, which can be a normal filter, and inverted filter, a compound filter, or another configurable filter. That means that e.g. c/exclude/query/siren/
is totally legitimate. Note that instead of doing c/exclude/has-links/
(that is, excluding a normal filter), it's best to just do the inverted version of that filter, e.g. in this case c/no-links/
.
Another type is combine
. It's like the ability to do a union filter of normal filters (e.g. starred+half-baked
), but it can operate on configurable filters. It takes two separate sub-filters and returns their union. So for example combine/query/siren/children/g487aed6370_0_45/
would return results that include the word 'siren' or are children of card g487aed6370_0_45.
Another type id author/ID1+ID2
, which will match any cards with any authors (or collaborators) named by the list of IDs, separated by a +
. 1 or more IDs are supported. The special id of me
will match the currently signed-in user. So you could do author/me
to see only cards you authored.
Another type is same-type/CARD-ID
, which matches any card that has the same card-type as the given card. different-type
is similar but opposite.
Another type is about-concept/concept+str
. This selects any cards that are about the given concept. concept+string
can be either a string representing the concept to pivot off of, or the ID of the concept card.
Another type is missing-concept/concept+str
. This selects cards that appear to reference the given concept but don't yet have an explicit concept reference--that is, if you were to open them to edit them, they wouldn't let you save without either accepting or rejecting the suggested concept. concept+str
may be either a string for the concept in question, or the concept card ID, or the special character +
, which means "any card that is missing any suggested concept".
Date based configurable filters have this form: PROPERTYNAME/DATESELECTOR
, where PROPERTYNAME can be either updated
or last-tweeted
, and DATESELECTOR can be before/DATE
, after/DATE
, between/DATE1/DATE2
, where DATE is any string that can be parsed by a Javascript new Date(), and typically is something like 2020-3-10
. For between, the dates can be in either order.
Another type of multi-part filter is the link filters. They all start with a keyword, then a card ID or slug, and then the ones that take a configurable number are followed by an integer. If the card ID or slug is prepended with +
then that key card will be included in the filter, otherwise it will be excluded and only other cards that it links to will be. There are three types: descendants
for all cards that are linked out from this card, ancestors
for following inbound links up, and connections
which combines both descendants and ancestors. These filters will treat as links any substantive reference type (i.e. anything other than 'ack'). The integer is how many 'ply' deep to go--how many layers to go in the BFS. If the provided ply is 0, then it's treated as infinite, which means it will return any cards that are transitively reachable from the given key card. There are also variants that filter to only work for a given type of reference. These are references
, references-inbound
, and references-outbound
. These take a CARD-ID, then a type of reference to use, then the ply. The type of reference may be a single string, like 'mined-from', or a union of multiple types, like 'mined-from+link', and if the reference type starts with '-' it means "all reference types that are NOT the ones provided," e.g. '-mined-from+link'. As a special case, for the case of the count int being 1, you can skip the integer by using the special direct styles of filters: children
, parents
, direct-connections
, direct-references
, direct-references-inbound
, direct-references-outbound
. These filters also introduce their own sort order by default based on how many degrees of separation the cards are. If you want the normal sort order, append sort/original-order
to your URL.
Another type of configurable filter is limit
, which takes a single argument, the number of cards to limit to, e.g. limit/10
would limit to show only the first 10 cards. The cards that are selected are the first n after the collection is in final sorted order.
Another type of configurable filter is similar
, which takes a single argument (the cardID to key off of) and filters cards based on how similar they are. The cardID can be preprended with a +
to include that key card in the returned set. This filter is a bit odd in that it doesn't actually filter out anything (except for the key card, if there's no +
), but rather is used for its implicit sort values. It's typically used in conjunction with limit, e.g. c/similar/c-123-45678/limit/5/
.
The final type of configurable filter is cards
, which takes one argument: a list of ids or slugs of cards to match, with multiple identifiers separated by +
. This filter is typically used in conjunction with exclude
, e.g. c/has-content/exclude/cards/complex-complicated/
-
starred
/unstarred
-
read
/unread
- One for each section and tag name
You can also combine multiple filters into a union, instead of an or, by using a +
character. For example starred+read
would match cards that were starred or read. Note that this only works for non-configurable filters; if you want to union filters that include configurable filters, see combine
above.
There are a number of sorts:
-
default
- Each card in order that they appear in their section, with each section in order by their ordinal, unless a configurable filter like the link-degree ones are used, in which case it will sort based on that. -
original-order
- Likedefault
, but always uses the original order of the cards, even if a configurable filter with an overriding sort was used. -
recent
- Reverse chronological order of when cards have been substantively edited OR commented on -
link-count
- Descending by number of inbound links -
updated
- Descending order of last substantive edit -
stars
- Descending by number of stars -
commented
- Descending by when they were last commented on -
last-tweeted
- Descending by when they were last tweeted by the bot -
tweet-count
- Descending by how many times they've been tweeted -
tweet-order
- The order the bot will tweet them out in -
todo-difficulty
- Orders cards by how difficult their total remaining TODOs are. Typically used in conjunction with a filter likeunpublished
, since cards that are published and have no remaining TODOs will be at the top of the list. Useful for finding the cards that need just a bit of work to publish. -
card-rank
- The 'page rank' for cards, where cards that are linked to from important cards get higher rank.
Only a single sort can be applied at a time.
Technically all of these filters and sorts are based off of a set --the set of ordered cards. In practice, you're almost always using the default set, called main
, and it's elided from the URL. The other two sets you might use are reading-list
(the user's personal reading list, in their own personal order), and everything
--which includes literally every card, including ones that aren't in any section.
When you edit a card, there's a box for 'Substantive'. This should be checked if the edit you're doing changed enough that someone might conceivably want to read the card again. Its meant to differentiate between edits that are minor or typo-fixing and edits that add content. Certain types of edits, like changing the section of a card or toggling whether it is published, automatically turn on the substantive box.
The only real difference for substantive edits is that un-substantive edits are ignored when doing sorts based on recent.