From 9489c43e5a38dec590d14548c3b07bd56eae8c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Tue, 19 Dec 2023 08:41:53 +0200 Subject: [PATCH 1/1] Changed order of sections; added UI Tips --- app-guide.gmi | 253 ++++++++++++++++++++++++++------------------------ 1 file changed, 130 insertions(+), 123 deletions(-) diff --git a/app-guide.gmi b/app-guide.gmi index 1323e36..797af94 100644 --- a/app-guide.gmi +++ b/app-guide.gmi @@ -18,11 +18,11 @@ The Gemini software ecosystem is quite heterogeneous: there are multiple server To get a sense of what Gemini apps can be like in practice, here is a sampling of interactive capsules: -=> gemini://geminispace.info A search engine -=> gemini://kennedy.gemi.dev A more advanced search engine -=> gemini://station.martinrue.com Microblogging site -=> gemini://bbs.geminispace.org Bulletin board system -=> gemini://astrobotany.mozz.us Gardening game +=> gemini://geminispace.info A search engine +=> gemini://kennedy.gemi.dev A more advanced search engine +=> gemini://station.martinrue.com Microblogging site +=> gemini://bbs.geminispace.org Bulletin board system +=> gemini://astrobotany.mozz.us Gardening game => gemini://spellbinding.tilde.cafe Word spelling game ## Overview of the guide @@ -40,22 +40,133 @@ Let's begin by taking a look at a basic Gemini CGI program. This will give you a (minimal and naive example of a Gemini CGI app using Python) -# 2. Receiving input +# 2. User interface -The fundamental difference between a static Gemini capsule and a Gemini app is that the application does something dynamic based on input provided by the user. +A key part of application design, and also programming in general, is to separate the public interface from the internal implementation. The needs of the human user and the internal technical implementation are very different and often at odds with each other. Nevertheless, both facets of an application are crucial and neither is compromised by the other. + +In practice, when it comes to Gemini applications, the user interface is built out of one or more dynamically generated Gemtext ("text/gemini") pages. + +Gemtext is quite a limited format for presenting a UI, which makes for an interesting design challenge. One issue is that the UI of your application should work — or at least strive to work — equally well with every Gemini client out there. Especially you should be wary of testing your application only on high-end graphical clients, where you have sophisticated page layout, multiple fonts, and color schemes that clarify the structure of the page. When viewing such pages in a terminal-based client, things may look different in unexpected ways. For example, clients may display links in different ways, and since links are used for most user actions and menus, it is important for them to remain legible and accessible. Still, Gemtext is simple enough that by following a few basic rules, you can achieve good results everywhere. One rule of thumb is that your UI should be comprehensible even when viewed as a plain-text Gemtext source file without any visual formatting. + +In this section, we will take a closer look at the options and tools at your disposal when it comes to the UI. + +## 2.1 Structure and path hierarchy + +Begin your UI design by considering what kind of high-level structure the application should have. Your UI will be constructed out of a URL path hierarchy and, on each page, links, headings and whitespace that delineate the content into different sections. + +As websites have been growing more and more complex, web browsers have been gradually phasing out visibility of the current page's URL, because it may mostly appear as visual noise to the user. Gemini clients typically do not do this, and one should consider the URL and its structure as part of the UI of the application. + +Tying the path hierarchy to the application's user-visible objects is useful because it is one way to communicate structure to the user and it enables clients to navigate the hierarchy more conveniently. For example, one can go up one directory level or go all the way to the root of the hierarchy. When it comes to CGI applications, there is no need to expose your local directory structure in URLs, even if you are serving files from directories. The URL directory structure can use an entirely virtual hierarchy, so always consider first what makes sense from the point of view of the user. + +If the directory hierarchy is deep, you may find that you are not actually using all the intermediate subdirectories along the path. It is good to use the client's "go up" or "go to parent" navigation features to check that each level of the URL hirerachy returns some meaningful content. One option is to respond with a redirect from parts of the path that are not very useful on their own, or have not been implemented in your application. + +Finally, as a matter of taste and if your server supports it, consider leaving out any "/cgi-bin/" prefixes out of your URLs. Removing unnecessary components makes the URL easier to read, understand, and remember, thus helping the user navigate your application more easily. Technical implementation details such as "cgi-bin" should not pollute the user interface of your application, causing distraction and potential confusion. + +## 2.2 Menus + +Menus are a very common UI element. A basic menu is a list of links: +``` +=> inbox/ Inbox +=> outbox/ Outbox +=> settings/ Settings +=> ../ Exit +``` + +You should strive to separate menus from normal content to make the UI more intuitive; the interactive parts should be distinct and identifiable at a glance. The easiest and most obvious method is to surround menus with empy lines. Overall, remember that the use of whitespace is a big part of any design language and this applies to Gemtext-based UIs as well, especially because the specification requires clients to retain empty lines when laying out the page. There is a difference between one and two (or more) empty lines, and this can be used for different types of sectioning. Keep the use of whitespace consistent to help communicate the structure of the UI to the user. + +One popular method to make menu items distinct is to employ Emoji as action icons. These additional visual cues can make the menu more glanceable and facilitate repeated access. Once one learns which actions are available in the menu, one can quickly locate the desired action just by looking at the icons. +``` +=> inbox/ đŸ“Ĩ Inbox +=> outbox/ 📤 Outbox +=> settings/ âš™ī¸ Settings +=> ../ â†Šī¸ Exit +``` +Which looks like this in your client: + +=> inbox/ đŸ“Ĩ Inbox +=> outbox/ 📤 Outbox +=> settings/ âš™ī¸ Settings +=> ../ â†Šī¸ Exit + +While Gemtext defaults to UTF-8 and clients are assumed to generally support Unicode, Emoji are not universally available in all clients. The exact visual appearance of Emoji depends on the fonts available to the client, and particularly terminal-based TUI clients may have difficulty displaying Emoji properly. Therefore, you can use Emoji as secondary visual cues, but do not rely on them as independent interface element without any descriptive labels. One option for dealing with this is to have a setting for displaying ASCII-based "icons" instead of Emoji. In any case, ensure that the UI is legible and usable without Emoji as well, even though they may be the preferred visualization mode for actions. + +A menu with several actions will become very tall when viewed in a client, because links are typically each displayed on their own line. A long menu is difficult for the user to read through and this will obscure other parts of the page — one has only so much vertical space in a client. If your menu seems to grow too long, you can split off parts in submenus that open new pages with more actions. Organizing submenus in a logical fashion is important. If a logical hierarchy is difficult to construct, another approach is to consider how frequently each action is needed and split off infrequent ones behind a "More..." link. + +When it comes to labeling actions, consistency should be the first priority. One recommended pattern to follow is to make every action label an unambiguous command using verbs in imperative form: +``` +=> inbox/ đŸ“Ĩ View inbox +=> outbox/ 📤 View outbox +=> settings/ âš™ī¸ Configure settings +=> ../ â†Šī¸ Exit +``` + +Placing a menu at the top of a page makes it easy for the user to find it and choose an action. However, this also means the menu takes priority over actual page contents and one may need to scroll past the menu to get to the content. Forcing the user to do this repeatedly may get annoying. Therefore, keep menus at the top as short as possible, with only the most commonly needed actions. For the rest of the actions, consider a secondary menu at the bottom of the page, following the actual page content. Many clients have a feature that allows instantly jumping to the bottom of the page, so this menu can be quickly accessed as well, although the user may not discover it as easily. A menu at the bottom can be longer and it can feature infrequently needed items, as the bottom area is out of the way. + +If you need multiple menus on the same page, consider giving them titles with heading lines. Some clients support an outline view and/or navigating to specific headings on a page, so this can help locate the right menu without scrolling around too much. + +## 2.3 Preformatted blocks + +Gemtext's visual limitations may tempt you to spice up the UI with "graphical" elements inside preformatted text blocks. Used tastefully, these will give the application a unique identity and appearance, and may help the user understand the structure of the UI more intuitively: a graphical element catches the eye, helping draw attention to a specific region of the page. However, if these elements are overused, the UI becomes unwieldy. A nice piece of ASCII art is great for welcoming users on the application's front page, but one wouldn't want to scroll over one on every page to access the application's core functions. As a rule, less is more. + +Preformatted blocks will limit your UI's adaptibility to different viewing devices, because as a rule clients will respect the formatting inside the block and not apply, say, additional line wrapping. Consider different screen and font sizes, and text-to-speech accessibility. Always include something meaningful in the "alt text" section of the preformatted block. It could be a textual version of the block's contents, a summary of the presented information, or some other explanation of the purpose of the block. This way, the UI will be more accessible to non-visual users. + +## 2.4 Lists + +Lists are another commonly needed UI element. For example, your application may need to display a set of inventory items, discussion threads, or search results. Gemtext has a line type for bulleted lists, but it is more suited for prose rather than a user interface, especially if the listed items are also accompanied by action links. If you mix up too many Gemtext line types when presenting an item, the result may be difficult for the user to understand particularly if they have a different client than what you are used to. Some clients' visual representation of the line types may be incompatible with the needs of your UI. + +One solution that seems to work rather well is the "social sandwich", first seen on station.martinrue.com: + +```Example: Gemtext source code showing links and content lines that comprise two different items. +=> /header/1 Header action +First item's content paragraph with a maximum length and limited formatting. +=> /footer/1 Footer action + +=> /header/2 Header action +Second item's content paragraph with a maximum length and limited formatting. +=> /footer/2 Footer action +``` + +Each item is composed of a single line of content that uses no special formatting. (If this is user-submitted content, Gemtext formatting needs to be stripped out.) The length of the line is limited to some reasonable application-dependent width keep a single item from using too much space on the page. The content is preceded and followed by an action link, without any blank space between the three lines. The items are separated by one or more blank lines. + +The header and footer actions can be chosen as appropriate for the application, and either one can be omitted if there is no need for two separate actions. In a social application with discussion threads, for example, the header action could link to the original poster's account, and the footer action could link to the discussion thread itself. Special attention should be placed on the labeling of these actions. An Emoji prefix helps make the header and footer more distinct and recognizable at a glance. Especially the header labels should be short to keep the main attention on the content line, so the reader is not distracted by a lot of metadata before getting to the content. + +## 2.5 Navigation links + +* help the user get around and understand where they are +* breadcrumbs? placement? +* navigation structures: query strings vs. directory structure ("Go Up" / "Go to Parent" navigation!), "Back to X" pages vs. knowing where the user came from +* client-side navigation: small pages can be fully cached, presented as-is from history; no cache control; user may see obsolete/old content; also benefits, like ability to see old versions of edited pages without the server having to save any history + +* remember client may have go up/root actions + +## 2.6 Tips + +* To get started, open up a blank .gmi file in your favorite text editor and write, by hand, a prototype version of your UI. You can preview the results in a client and fine-tune the prototype until you are happy with how it looks. Don't forget to try it in both graphical and text-based clients. + +# 3. Receiving input + +The fundamental difference between a static Gemini capsule and a Gemini application is that the latter does something dynamic based on input provided by the user. From the user's point of view, the possible methods for providing input are: * Opening a link in their client that causes an action in the application. * Entering text into an input prompt. -* Name fields stored in a TLS client certificate. (Section 3.2 goes into more detail about client certificates.) -* Sending data using other protocols, like SFTP, e-mail, or Titan. (For the purposes of this guide, we will ignore these. When it comes to your application, consider which other protocols would make sense and whether it provides significant enough benefit to justify the implementation cost. The important thing to keep in mind is that Gemini is best suited for sending small amounts of data at a time, so larger amounts are more convenient to send via other means.) +* Sharing information via name fields of a TLS client certificate. (Section 3.2 goes into more detail about client certificates.) +* Sending data using other protocols, like SFTP, e-mail, or Titan. -On server-side, the application typically runs inside a CGI environment launched by the server, where your code is able to access all relevant parts of incoming requests via environment variables. It is also possible that your application responds to Gemini requests directly, but that requires code for handling incoming TLS connections according to the Gemini protocol specification. (See section 5 for discussion about applications that run as a standalone server.) For now, let us assume that the application is run via CGI. +When it comes to non-Gemini protocols, for the purposes of this guide, we will ignore them. As a rule, attempt to make your application fully usable with nothing but Gemini requests. This makes it compatible with all the clients out there. (Even the one that you one day may write yourself!) When it comes to your application, consider which other protocols would make sense for a substantially improved user experience and whether it provides significant enough benefit to justify the implementation cost. The important thing to keep in mind is that Gemini is best suited for sending small amounts of data (1024 bytes) at a time, so larger amounts are more convenient to send via other means. + +On server-side, the application typically runs inside a CGI environment launched by the server, where your code is able to access all relevant parts of incoming requests via environment variables. It is also possible that your application responds to Gemini requests directly, but that requires code for manually handling incoming TLS connections. (See section 6 for discussion about applications that run as a standalone server.) For now, let us assume that the application runs via CGI. There may be server-specific differences in the CGI environment, but typically the following variables are available: -* +* (environment variables) + +## Decoding the request + +User-provided data most often comes in to your application via the request URI. To a CGI application, the data is available as the `PATH_INFO`, `PATH_TRANSLATED`, and `QUERY_STRING` environment variables. Even if you are only ever using the decoded versions of the data, it is good to know how it gets processed along the way. + +The request URI must be a percent-encoded text string up to 1024 bytes in length. After decoding, the result is a UTF-8 text string. UTF-8 and URL percent-coding: * make your app entirely usable on Gemini URLs alone, query strings @@ -68,13 +179,13 @@ User input: * other ways to deal with the URL length limitation of 1024 bytes: compose longer content in pieces, one chunk at a time; link to an external location that the server can download (indirect upload); use supplementary protocols like Titan, email, SFTP, but those should not be considered universally supported * email input: note that "mailto:" URLs support prefilled addresses and message body, these could be used for temporary session tokens or other metadata required to save the received contents to the right place in the app, for a better UX -- but note that email is usually transmitted as plain text; incorporate PGP encryption keys? that would also verify the identity of the sender without any session tickets or certificate fingerprints -# 3. Sessions and users +# 4. Sessions and users A central design decision is whether your application needs to have per-session and per-user data, and how these will be stored and maintained. While many applications, such as search engines, weather services, and simple games, can function without any knowledge about the user, more sophisticated applications typically have some per-user state that needs to be tracked in a private and secure manner. For example, the application could have per-user preferences, a player inventory, or an internal messaging system, and this data needs to be stored persistently on the server. -# 3.1 Anonymous usage +## 4.1 Anonymous usage Anonymous usage means that the Gemini server and your application have no way of identifying the user who sent a particular request, apart from the ever-present but ambiguous IP address. @@ -119,7 +230,7 @@ A notable potential downside of anonymous usage is that search engine crawlers a => gemini://gemini.circumlunar.space/docs/companion/robots.gmi robots.txt for Gemini -# 3.2 Client certificates +## 4.2 Client certificates You should already be familiar with how and why Gemini uses TLS. When it comes to Gemini applications, the most interesting part of TLS is client certificates. @@ -127,6 +238,7 @@ You should already be familiar with how and why Gemini uses TLS. When it comes t TLS client certificates are what enable Gemini applications to keep track of individual sessions and user accounts in a secure and privacy-respecting manner. It is therefore good to understand the mechanics of TLS, and client certificates in particular, a bit more deeply. +* URL authority: the traditional solution of username and password (?) -- Gemini spec says to not use? -- certificates have security advantages over passwords, if one keeps the private key properly secret * standard part of TLS, not that widely used on the web, though * when to use; it is not impossible to create stateful apps without certs, and that might be an option for casual apps like games, where the entire state can be encoded into the URL somehow (independently, or as a session token); certs are very much the recommended way to build apps, though; fully supported and protected via TLS * how to use? @@ -135,7 +247,7 @@ TLS client certificates are what enable Gemini applications to keep track of ind * how do they work, exactly? TLS basics, private key, meaning of self-signing, issuer/subject common names, server-side data (X.509 certificate, public key, fingerprint SHA-256 hashes), expiry (!) * potential for misuse; servers that log/share key or certificate fingerprints for tracking purposes, perhaps mostly a theoretical concern -## 3.3 User accounts +## 4.3 User accounts Your application may need user accounts so it has a way to manage per-user data. @@ -151,112 +263,7 @@ There are two ways you can approach user accounts in a Gemini application: * identity verification: how to know whether someone is who they claim they are, given certs are self-signed? you don't, so don't trust blindly; backlinks from user's capsule may provide additional verification (incl. cert recovery URL) * lost/expired certificates: how to mitigate issues? a simple one-cert-per-user setup is prone to drawbacks, although very easy to implement; assume that client certificates are always temporary, even if expiration is in 1000 years (!); registering multiple certificates per user; passwords -- prefer certificates only for persistent use, though, since the whole point is to avoid needing passwords; certificate recovery URL; instruct user about appropriate expiration time when creating account -# 4. User interface - -A key part of application design, and also programming in general, is to separate the public interface from the internal implementation. The needs of the human user and the internal technical implementation are very different and often at odds with each other. Nevertheless, both facets of an application are crucial and neither is compromised by the other. - -In practice, when it comes to Gemini applications, the user interface is built out of one or more dynamically generated Gemtext ("text/gemini") pages. - -Gemtext is quite a limited format for presenting a UI, which makes for an interesting design challenge. One issue is that the UI of your application should work — or at least strive to work — equally well with every Gemini client out there. Especially you should be wary of testing your application only on high-end graphical clients, where you have sophisticated page layout, multiple fonts, and color schemes that clarify the structure of the page. When viewing such pages in a terminal-based client, things may look different in unexpected ways. For example, clients may display links in different ways, and since links are used for most user actions and menus, it is important for them to remain legible and accessible. Still, Gemtext is simple enough that by following a few basic rules, you can achieve good results everywhere. One rule of thumb is that your UI should be comprehensible even when viewed as a plain-text Gemtext source file without any visual formatting. - -In this section, we will take a closer look at the options and tools at your disposal when it comes to the UI. - -## 4.1 Structure - -Begin your UI design by considering what kind of high-level structure the application should have. Your UI will be constructed out of a URL path hierarchy and, on each page, links, headings and whitespace that delineate the content into different sections. - -### Path hierarchy - -As websites have been growing more and more complex, web browsers have been gradually phasing out visibility of the current page's URL, because it may mostly appear as visual noise to the user. Gemini clients typically do not do this, and one should consider the URL and its structure as part of the UI of the application. - -Tying the path hierarchy to the application's user-visible objects is useful because it is one way to communicate structure to the user and it enables clients to navigate the hierarchy more conveniently. For example, one can go up one directory level or go all the way to the root of the hierarchy. When it comes to CGI applications, there is no need to expose your local directory structure in URLs, even if you are serving files from directories. The URL directory structure can use an entirely virtual hierarchy, so always consider first what makes sense from the point of view of the user. - -If the directory hierarchy is deep, you may find that you are not actually using all the intermediate subdirectories along the path. It is good to use the client's "go up" or "go to parent" navigation features to check that each level of the URL hirerachy returns some meaningful content. One option is to respond with a redirect from parts of the path that are not very useful on their own, or have not been implemented in your application. - - - -Finally, as a matter of taste and if your server supports it, consider leaving out any "/cgi-bin/" prefixes out of your URLs. Removing unnecessary components makes the URL easier to read, understand, and remember, thus helping the user navigate your application more easily. - -* URL authority: username and password (?) -- Gemini spec says to not use? - -### Menus - -Menus are a very common UI element. A basic menu is a list of links: -``` -=> inbox/ Inbox -=> outbox/ Outbox -=> settings/ Settings -=> ../ Exit -``` - -You should strive to separate menus from normal content to make the UI more intuitive; the interactive parts should be distinct and identifiable at a glance. The easiest and most obvious method is to surround menus with empy lines. Overall, remember that the use of whitespace is a big part of any design language and this applies to Gemtext-based UIs as well, especially because the specification requires clients to retain empty lines when laying out the page. There is a difference between one and two (or more) empty lines, and this can be used for different types of sectioning. Keep the use of whitespace consistent to help communicate the structure of the UI to the user. - -One popular method to make menu items distinct is to employ Emoji as action icons. These additional visual cues can make the menu more glanceable and facilitate repeated access. Once one learns which actions are available in the menu, one can quickly locate the desired action just by looking at the icons. -``` -=> inbox/ đŸ“Ĩ Inbox -=> outbox/ 📤 Outbox -=> settings/ âš™ī¸ Settings -=> ../ â†Šī¸ Exit -``` -Which looks like this in your client: - -=> inbox/ đŸ“Ĩ Inbox -=> outbox/ 📤 Outbox -=> settings/ âš™ī¸ Settings -=> ../ â†Šī¸ Exit - -While Gemtext defaults to UTF-8 and clients are assumed to generally support Unicode, Emoji are not universally available in all clients. The exact visual appearance of Emoji depends on the fonts available to the client, and particularly terminal-based TUI clients may have difficulty displaying Emoji properly. Therefore, you can use Emoji as secondary visual cues, but do not rely on them as independent interface element without any descriptive labels. One option for dealing with this is to have a setting for displaying ASCII-based "icons" instead of Emoji. In any case, ensure that the UI is legible and usable without Emoji as well, even though they may be the preferred visualization mode for actions. - -A menu with several actions will become very tall when viewed in a client, because links are typically each displayed on their own line. A long menu is difficult for the user to read through and this will obscure other parts of the page — one has only so much vertical space in a client. If your menu seems to grow too long, you can split off parts in submenus that open new pages with more actions. Organizing submenus in a logical fashion is important. If a logical hierarchy is difficult to construct, another approach is to consider how frequently each action is needed and split off infrequent ones behind a "More..." link. - -When it comes to labeling actions, consistency should be the first priority. One recommended pattern to follow is to make every action label an unambiguous command using verbs in imperative form: -``` -=> inbox/ đŸ“Ĩ View inbox -=> outbox/ 📤 View outbox -=> settings/ âš™ī¸ Configure settings -=> ../ â†Šī¸ Exit -``` - -Placing a menu at the top of a page makes it easy for the user to find it and choose an action. However, this also means the menu takes priority over actual page contents and one may need to scroll past the menu to get to the content. Forcing the user to do this repeatedly may get annoying. Therefore, keep menus at the top as short as possible, with only the most commonly needed actions. For the rest of the actions, consider a secondary menu at the bottom of the page, following the actual page content. Many clients have a feature that allows instantly jumping to the bottom of the page, so this menu can be quickly accessed as well, although the user may not discover it as easily. A menu at the bottom can be longer and it can feature infrequently needed items, as the bottom area is out of the way. - -If you need multiple menus on the same page, consider giving them titles with heading lines. Some clients support an outline view and/or navigating to specific headings on a page, so this can help locate the right menu without scrolling around too much. - -### Preformatted blocks - -Gemtext's visual limitations may tempt you to spice up the UI with "graphical" elements inside preformatted text blocks. Used tastefully, these will give the application a unique identity and appearance, and may help the user understand the structure of the UI more intuitively: a graphical element catches the eye, helping draw attention to a specific region of the page. However, if these elements are overused, the UI becomes unwieldy. A nice piece of ASCII art is great for welcoming users on the application's front page, but one wouldn't want to scroll over one on every page to access the application's core functions. As a rule, less is more. - -Preformatted blocks will limit your UI's adaptibility to different viewing devices, because as a rule clients will respect the formatting inside the block and not apply, say, additional line wrapping. Consider different screen and font sizes, and text-to-speech accessibility. Always include something meaningful in the "alt text" section of the preformatted block. It could be a textual version of the block's contents, a summary of the presented information, or some other explanation of the purpose of the block. This way, the UI will be more accessible to non-visual users. - -### Lists - -Lists are another commonly needed UI element. For example, your application may need to display a set of inventory items, discussion threads, or search results. Gemtext has a line type for bulleted lists, but it is more suited for prose rather than a user interface, especially if the listed items are also accompanied by action links. If you mix up too many Gemtext line types when presenting an item, the result may be difficult for the user to understand particularly if they have a different client than what you are used to. Some clients' visual representation of the line types may be incompatible with the needs of your UI. - -One solution that seems to work rather well is the "social sandwich", first seen on station.martinrue.com: - -```Example: Gemtext source code showing links and content lines that comprise two different items. -=> /header/1 Header action -First item's content paragraph with a maximum length and limited formatting. -=> /footer/1 Footer action - -=> /header/2 Header action -Second item's content paragraph with a maximum length and limited formatting. -=> /footer/2 Footer action -``` - -Each item is composed of a single line of content that uses no special formatting. (If this is user-submitted content, Gemtext formatting needs to be stripped out.) The length of the line is limited to some reasonable application-dependent width keep a single item from using too much space on the page. The content is preceded and followed by an action link, without any blank space between the three lines. The items are separated by one or more blank lines. - -The header and footer actions can be chosen as appropriate for the application, and either one can be omitted if there is no need for two separate actions. In a social application with discussion threads, for example, the header action could link to the original poster's account, and the footer action could link to the discussion thread itself. Special attention should be placed on the labeling of these actions. An Emoji prefix helps make the header and footer more distinct and recognizable at a glance. Especially the header labels should be short to keep the main attention on the content line, so the reader is not distracted by a lot of metadata before getting to the content. - -### Navigation links - -* help the user get around and understand where they are -* breadcrumbs? placement? -* navigation structures: query strings vs. directory structure ("Go Up" / "Go to Parent" navigation!), "Back to X" pages vs. knowing where the user came from -* client-side navigation: small pages can be fully cached, presented as-is from history; no cache control; user may see obsolete/old content; also benefits, like ability to see old versions of edited pages without the server having to save any history - -* remember client may have go up/root actions - -## 4.2 Security considerations +# 5. Security considerations In Geminispace, in the absense of financial motivations, a malicious user could be driven by a personal grudge or a desire to make a scene and cause emotional reactions. The simplicity of both the protocol and Gemtext syntax lower the bar for automated attacks. @@ -267,7 +274,7 @@ In Geminispace, in the absense of financial motivations, a malicious user could * confirming actions with query string: always a good idea to confirm an action that leads to data loss; note that any link on a page could come with a "?yes-really" confirmation query string already included, so it could be wise to make the confirmation prompt dynamic ("What is the third number in this sequence? 34 Hello 11 8") * spam/malicious bots: Gemini is small, relatively obscure, and lacks financial incentives for spam, so to a degree this will protect your app from abuse, but one should still consider potential malicious requests; a bot could generate a self-signed certificate and start submitting requests to your app, although such bots would have to be tailed-made to target specific capsules; ultimately what you should do about it depends on your app -- additional steps and verification factors in user registration may be warranted in cases of repeated/automated abuse. -# 5. Internals +# 6. Internals * CGI environment, cf. official/Sean's documentation, server's own documentation * what to do with the cert/pubkey hash; storing in database or persistent storage, security implications (TLS-backed); what do the variables mean and how to use them @@ -276,7 +283,7 @@ In Geminispace, in the absense of financial motivations, a malicious user could * similarities to web apps: prepare for parallel request processing; full-blown vs. SQLite databases * Python, PHP, Lua, Rust (?); libraries and frameworks for implementing a Gemini server -# 5.1 Alternatives to CGI +## 6.1 Alternatives to CGI * while CGI is quite versatile, it still assumes input to arrive via environment variables and output via stdout, with each request spawning a CGI process; this may not be optimal for all apps; see also: FastCGI * a bespoke app server is not too difficult to pull off, given Gemini's simplicity; could use an off-the-shelf solution: Sean Conner's GLV (?), mozz's JetForce (?), or skyjake's GmCapsule -- this could also be considered a possible optimization in case CGI becomes a hindrance -- 2.34.1