[{"content":"Hello there, my name is Don Geronimo. The worldwide pandemic has affected all of our lives, and I\u0026rsquo;m thankful that I\u0026rsquo;ve been able to reclaim my life as a flight attendant once more. While I’m currently not looking for any other career opportunities, if I can volunteer or help out in any way I can, I invite you to speak with me!\nIndustry Knowledge  Administrative Assistance Contact Tracing First Aid Flight Attendant FAA FA Supervisor Hospitality Inventory Management Restaurant Management Safety Reporting Sales Security Social Media   Tools and Technologies  Angular AED C# CPR CSS Debian EPUB Fedora GIMP HTML5 Hugo JavaScript Linux Microsoft Office Microsoft Teams PHP RDFa Salesforce SQL Twilio TypeScript WBAT Windows Zoom   Interpersonal Skills  Conflict Resolution CRM (Aviation) CRM (Sales) Employee Relations Hiring Team Building Training   Languages  English Filipino   Experience Flight Attendant Delta Air Lines Inc.(DL) - Atlanta, GA, 30354, USA Worked: From February 2020 to Present\nAs a flight attendant, I am in charge of making sure our inflight policies as set through our corporate standards and the code of federal regulations are followed to ensure the safety, security, and comfort of our passengers and planes. In addition to following the rules and regulations set in our manuals and handbooks, I inform other flight attendants and the company of potential safety and security incidents by conversations about safety concerns and through proper reporting channels. Finally, I am charged with providing bold hospitality and excellent customer service to delight passengers and encourage them to continue to fly with us.\nStarted with Delta Air Lines Inc. on February 17th, 2020   Self-Employed Don Geronimo Consulting - South Elgin, IL, 60177, USA Worked: From June 2008 to Present\nI have done content creation, web design, eBook binding and publishing, social media strategy setup, and digital print design projects as a freelance consultant since 2008. My focus has been on small businesses who needed help starting up their Internet and social media presence, writers who want to publish their works to digital platforms, and aspiring bloggers and experts who need help getting started.\n Contact Tracing Specialist DuPage County Health Department - Wheaton, IL, 60187, USA Worked: From March 2021 to July 2021\nContact tracing is the process of identification of persons who may have come into contact with an infected person (\"contacts\") and subsequent collection of further information about these contacts. By tracing the contacts of infected individuals, testing them for infection, isolating or treating the infected and tracing their contacts in turn, public health aims to reduce infections in the population. I provide a helpful resource for individuals who may have been exposed to COVID-19 to take care of themselves and of others during this pandemic. Through effective communication strategies I provide assurances, support, and resources for people who may be infected. Through following standards and policies I ensure that cases can be tracked to better isolate and reduce the infections in my area and beyond in a caring, compassionate, and privacy-respecting manner.\nStarted with DuPage County Health Department on March 15th, 2021 Ended with DuPage County Health Department on July 31th, 2021   Contact Tracer TTEC Healthcare Solutions Inc. - Englewood, CO, 80112, USA Worked: From August 2020 to February 2021\nContact tracing is the process of identification of persons who may have come into contact with an infected person (\"contacts\") and subsequent collection of further information about these contacts. By tracing the contacts of infected individuals, testing them for infection, isolating or treating the infected and tracing their contacts in turn, public health aims to reduce infections in the population. I provide a helpful resource for individuals who may have been exposed to COVID-19 to take care of themselves and of others during this pandemic. Through effective communication strategies I provide assurances, support, and resources for people who may be infected. Through following standards and policies I ensure that cases can be tracked to better isolate and reduce the infections in my area and beyond in a caring, compassionate, and privacy-respecting manner.\nStarted with TTEC Healthcare Solutions Inc. on August 8th, 2020 Ended with TTEC Healthcare Solutions Inc. on February 28th, 2021   Check Flight Attendant Frontier Airlines(F9) - Denver, CO, 80239, USA Worked: From March 2019 to January 2020\nThis is a USA FAA-required position for airlines under 14 CFR § 121.434. The Check Flight Attendant role is a qualified Flight Attendant Supervisor who personally observes the performance of new flight attendants performing their duties on their Initial Operating Experience (IOE). My role in the process is to assess their competency to work as a required crewmember without supervision and to be a resource for new and current flight attendants on government regulations and company policies, contract, and guidelines.\nStarted with Frontier Airlines on August 12th 2016 Ended with Frontier Airlines on January 31st 2020   Flight Attendant Frontier Airlines - Denver, CO, 80239, USA Worked: From August 2016 to January 2020\nAs a flight attendant, I am in charge of making sure our inflight policies as set through our corporate standards and the code of federal regulations are followed to ensure the safety, security, and comfort of our passengers and planes. In addition to following the rules and regulations set in our manuals and handbooks, I inform other flight attendants and the company of potential safety and security incidents by conversations about safety concerns and through WBAT.\n Account Manager SourceMob LLC - Wayzata, MN, 55391, USA Worked: From March 2015 to March 2016\nI started with SourceMob LLC to make Human Resources easier and more social, providing operations administrative support, data entry and analysis, customer relationship management, and various other tasks that take advantage of my diverse skillset and can-do attitude.\nStarted with SourceMob LLC on March 5th, 2015 Ended with SourceMob LLC on March 1st 2016   Assistant Manager Smashburger - Saint Paul, MN, 55116, USA Worked: From September 2011 to January 2015\nStarting as a Guest Service Expert, I volunteered to learn more about the restaurant business in a span of two years to learn to be a Cook, become a Shift Leader, and learn the foundational skills to eventually become part of management proper. Training new team members and shift leaders, enforcing corporate excellence and health standards, managing inventory and recipes to reduce shrinkage, and keeping consistent and amicable customer service skills was my day to day.\nStarted with Smashburger on September 29th 2011 Ended with Smashburger on January 31st 2015    Projects Is Your Social Recruiting Toast Burning?: The Ultimate Talent Acquisition Guide February 2016 I have handled the binding and Amazon Kindle publication of Jeffery Giesener's Is Your Social Recruiting Toast Burning?, a compilation of experience assisting many companies—big and small—on using Internet and Social media best practices to broadcast company content information and open jobs into engaging channels where candidates search for jobs.\nCSS pages were refined and SVG was utilized in images to make the reflowable ePub consistent-looking between platforms and devices. After less than one month of availability on Amazon, Is Your Social Recruiting Toast Burning? is #217 in Social Media for Business, #356 in Social Media, and #441 in Human Resources and Personnel Management.\n  Matthew Hope Website November - December 2014 A one-page website using HTML5 and JavaScript with jQuery to help promote a good friend and local musician in the Minneapolis, Minnesota, area. The project was designed for limited resources--no server-side scripting--and high accessibility in mind to ensure the widest audience.\n  The Frontage Road: An American Life September - December 2012 I hand-created an ePub-compliant eBook, ready to be published on Nook, Kindle, and iBooks, for Bob Tuff's memoir, The Frontage Road. SVG was used to properly and responsively scale on whatever eBook device is used, and many checks and validations were done to make sure rendering was consistent on all devices.\n  The Well-Travelled Guru June 2012 A one-page website hub using the (now-defunct) Flavors.me service for the blog posts and social updates of Lorna Rockey, the Well-Travelled Guru. In addition to making sure the connections stayed valid, I also took care of much of the technology involved in keeping it together and updated.\n  Affiliations Association of Flight Attendants - CWA LEC: 86 ORD Involvement: Member (Rank and File) from August 2016 to January 2020\nThe Association of Flight Attendants-CWA (AFA-CWA) is the flight attendant union organized by flight attendants for flight attendants. AFA represents nearly 50,000 flight attendants at 20 airlines, serving as a voice for flight attendants at their workplace, in the industry, in the media and on Capitol Hill. Simply put, the goal of flight attendants who become part of AFA-CWA is to negotiate better pay, benefits, working conditions and work rules at their airline, and to improve their safety on the job.   Certifications Contact Tracing Proficiency (CCTP) 4MedPlus Corporation - Valid Through June 13th, 2021(Issued June 13th, 2020)  Valid For: 1 Year The Certificate of Contact Tracing Proficiency course covers all CDC recommended training elements required to apply for a contact tracer role. Contact tracers are those who notify close contacts of pandemic patients of their exposures. After completing all training in this course, learners should be able to conduct contact tracing according to established protocols and demonstrate that they can:\n Identify strategies to reduce the spread of disease Identify the primary components of contact tracing List requirements for protecting health information Describe detailed contact tracing protocol Apply knowledge and contact tracing protocol to realistic scenarios Identify contact tracing tools and protocols Analyze contact tracing encounters for continuous quality improvement   Demonstrated Proficiency - Flight Attendant Group II Federal Aviation Administration - Valid Through April 1st, 2023(Issued August 12th, 2016)  Valid For: 18 Months In the fall of 2003, Congress established a flight attendant certification requirement in the Vision 100-Century of Aviation Reauthorization Act. The act requires that after December 11, 2004, no person may serve as a flight attendant aboard an aircraft of an air carrier unless that person holds a Certificate of Demonstrated Proficiency (certificate) issued by the FAA.\nThe act defines a flight attendant as an individual who works in the cabin of an aircraft that has 20 or more seats and is used by a part 121 or part 135 air carrier to provide air transportation. The FAA will not issue a Certificate of Demonstrated Proficiency to any flight attendant that does not meet this definition.\n HIPAA Workforce Proficiency (CHWP) 4MedPlus Corporation - Valid Through June 13th, 2021(Issued June 13th, 2020)  Valid For: 1 Year The Certificate of HIPAA Workforce Proficiency (CHWP) course provides training for workforce staff members, for a complete understanding of HIPAA compliance for medical professionals.\n Infection Control Basic Proficiency (CICBP) 4MedPlus Corporation - Valid Through June 13th, 2021(Issued June 13th, 2020)  Valid For: 1 Year This course and certificate provides and accredits learners with annually required training to address infection control and prevention. It is intended for all healthcare workers is is approved nationally by both ANCC and ACCME. This course is additionally PROVIDER APPROVED FOR ALL NY LICENSED HEALTHCARE PROFESSIONALS BY THE NEW YORK STATE DEPARTMENT OF HEALTH. MEETS REQUIREMENTS OF CHAPTER 786 OF THE NEW YORK STATE LAWS OF 1992 REGARDING BARRIER PRECAUTIONS AND INFECTION CONTROL MEASURES. (NEW YORK PROVIDER # I02234).\nCOURSE OBJECTIVES:\n Describe Mandated Infection Control and Barrier Protection Standards Describe Cleaning Disinfection and Sterilization (CDS) Discuss Awareness, Prevention and Control of Infectious Disease Explain Needle-Stick and Sharps Safety (NSS) Understand Bloodborne Pathogens Prevention (BBP) Recognize Personal Protective Equipment in Healthcare (PPE) Understand Hand Washing and Glove Requirements for Health \u0026amp; Safety Discuss Sepsis Awareness and Education CDC Guidelines Regarding COVID19/Coronavirus    Education Bachelor's Degree University of Saint Thomas - Saint Paul, MN, 55105, USA  Pursued: Music, Education; Mathematics Minor from 2005 to 2008 Grade-Point Average: 3.83 Activities and Societies: Aquinas Scholars, Dean's List, Allies, UniteUST, Concert Choir, Liturgical Choir, Open-Source Software Club  I went to college to pursue a Bachelor of Music degree in Music and Education, which required a major in both. I also chose to pursue Mathematics to better-diversify myself in an education environment.\n High School Diploma Chaska High School - Chaska, MN, 55318, USA  Pursued: High School Diploma from 2001 to 2015 Grade-Point Average: 3.96 Activites and Societies: Speech Team, National Honor Roll, Concert Choir  My high school career included a rigorous number of advanced placement classes in Government, Economics, Physics, Calculus, and French; along with the school's speech team and concert choir. I joined the national honor roll because of my consistently high grades and extracurricular activities. Private violin lessons occupied my time after school.\n ","id":"/resume/","summary":"While I\u0026rsquo;m currently not looking for any other career opportunities, if I can volunteer or help out in any way I can, I invite you to speak with me!","tag":"","title":"Résumé","type":"resume"},{"content":"Did I do something awesome for you lately and now you want to give me something more than just a heartfelt thanks and a warm fuzzy feeling in my chest? I’d be more than happy to accept a tip!\nBasic Attention Token (BAT) For those of you who use Brave Browser and opted in to the Brave Rewards program, I am a verified Creator. Just send me a tip, or add me to the creators who you automatically contribute to. The browser will automatically contribute to me each month based on how much attention you give me.\nStellar Lumens (XLM) I\u0026rsquo;ll happily accept a tip in XLM. You can send the tip in XLM, or in any other asset token you control in your wallet. Stellar\u0026rsquo;s path payments will automatically convert it at the best rate! Just send your tip to tip*sentamal.in using your favorite wallet app.\nOther Cryptocurrencies Gridcoin (GRC) Gridcoin is an open source cryptocurrency which securely rewards volunteer computing performed on the BOINC platform. Tips in GRC will allow me to stake blocks\u0026ndash;and get paid for the work my devices do\u0026ndash;more often. If you\u0026rsquo;d like to send me GRC, please e-mail or message me and I\u0026rsquo;ll send you an address to which you can send.\nBitcoin (BTC) For those of you who would like to tip me in BTC, please e-mail or message me and I\u0026rsquo;ll send you an address to which you can send.\nOther Methods If you\u0026rsquo;d prefer, I also accept tips via PayPal, Venmo, and Cash App.\nThank You! I have no need for tips or expect tips to be given, so I truly appreciate it whenever something is sent my way. Thank you so much for being kind!\n","id":"/buy-me-a-beer/","summary":"Did I do something awesome for you lately and now you want to give me something more than just a heartfelt thanks and a warm fuzzy feeling in my chest? I\u0026rsquo;d be more than happy to accept a tip!","tag":"","title":"Buy me a Beer!","type":"buy-me-a-beer"},{"content":"Too Long; Didn\u0026rsquo;t Read Do you want me to sign your key? Here’s how to do it:\n You better want to sign my key as well! Meet me somewhere reasonable for tea or a meal and pleasant conversation. Give me a hard copy of your key\u0026rsquo;s fingerprint and any photo IDs on it. Let me check two of your identity documents. One of them must have your picture. Afterwards, when I\u0026rsquo;m somewhere I think it\u0026rsquo;s safe to certify, I\u0026rsquo;ll sign your key and send it back to you.  Easy enough? If you want more details, you can read all the stuff below.\nPreamble This policy is valid from January 30, 2021, for all signatures made by the GnuPG key:\npub ed25519/0x1206BA5EDDF2FDF9 2018-04-04 [C] [expires: 2024-05-14] Key fingerprint = F4D7 9338 6981 E0AC A9C4 2787 1206 BA5E DDF2 FDF9 uid [ultimate] Don San Juan Geronimo \u0026lt;don.geronimo@outlook.com\u0026gt; uid [ultimate] Don San Juan Geronimo \u0026lt;dgeronimo@gmail.com\u0026gt; uid [ultimate] Don San Juan Geronimo \u0026lt;don.geronimo@protonmail.com\u0026gt; uid [ultimate] Don San Juan Geronimo \u0026lt;email@sentamal.in\u0026gt; uid [ultimate] [jpeg image of size 2871] The most recent version of this key is available from the URL above, by using the Web Key Directory for email@sentamal.in, from the key server at hkps.pool.sks-keyservers.net, or from Keybase.\nThis policy may be replaced at any time with a new version. If a new version incorporates changes that might affect the strength or perceived strength of the resulting signature, the old version will be linked from the new one.\nThis policy is signed with the above key and by Keybase. You may download this policy and its signatures for reference and verification.\nVersion Information and Changelog This is Version 4.5, written and signed by my key and by Keybase. Updated key expiration dates and photo.\n Previous Versions  Version 4.4, written and signed by my key and by Keybase. Removed 'Transition To New Key' section. Removed subkeys from the fingerprint above. Removed 'About keybase.io' section. Formatted to HTML. Version 4.3, written and signed. Removed 'themindfulworkflow.com' e-mail. Version 4.2, written and signed. Removed RSA encryption subkey. Added Protonmail e-mail as a UID. Removed section 'Temporary Revisions.' Version 4.1, written and signed. Removed subkeys from key material that will no longer be used. Version 4.0, written and signed. Added explanation about temporary revisions in Version Information and Changelog. Changed Levels of Signatures to only use Level 0 for certifying keys and user IDs and Level 3 for self-signatures to generalize potential social graphs. Updated Transition section to signify completion of transition. Minor word edits. Updated key expiration dates. Version 3.1, written and signed. Added additional signing and authentication subkeys to my public key material. Added TLDR section. Version 3.0, written and signed. Transition to using ECC key as the primary key in use. Added transition section with links to the transition statement. Revoked previous encryption subkey and added on, in this order, an RSA encryption subkey (for compatibility) and a CV25519 encryption subkey (which will be utilized first before the RSA key). Removed key expiration date. Version 2.0, written and signed. Transitioned all links from OneDrive to keybase.io. Added 'keybase.io' as an additional place that will count as a publically accessible key server in Prerequisites  Miscellaneous. Changed date formats to include leading zeroes. Added 'About keybase.io' section. Formatted the signing policy to Markdown. Added the image available in both keys. Added 'I will keep this copy for reference' in 'Hardcopy of Fingerprint.' Added 'Thank You For Visiting!' at the end of the document. Version 1.5, written and signed. Updated key with new Photographic UID. Added information about availability of a new primary key that utilizes ECC. Version 1.4, written and signed. Changed Identity Verification to require an additional form of identification. Moved signature levels of photographic UID to Level 2. Version 1.3, written and signed. Key fingerprint updated after updating the expiration date. Changed 'It may be replaced...' to 'This policy may be replaced...' to remove ambiguity. Added links to current document and signature to Version Information. Version 1.2, written and signed. Key fingerprint updated after revocation of the 'creativityzoo.com' user ID and addition of the 'themindfulworkflow.com' user ID. Location information was updated. Minor word changes. Version 1.1, written and signed. Minor grammar changes and section removal. Version 1.0, written and signed. The original document.   Location I currently reside in the western suburbs of Chicago, Illinois, United States. However, as a flight attendant, my profession takes me to various places around the continental United States. As such, the easiest way to meet with me to coordinate key verification would be to contact me via e-mail or Keybase to arrange a meeting.\nLevels of Signatures I utilize two certification levels:\n Level 0 (0x10): I will issue this level of signature if I have met the key owner who wishes to obtain a signature to their key from me (hereafter called the \u0026ldquo;signee\u0026rdquo;) in person and verified their identity according to the procedure below. Photographic UIDs will be signed at this level if I can still remember the signee\u0026rsquo;s face during the act of signing. Only signing UIDs at this level helps mitigate the possibility of leaking detailed social connections. Level 3 (0x13): This level of signature is reserved only for self signatures.  I do not utilize Level 1 (0x11) or Level 2 (0x12) certification levels.\nKeys of Certification Authorities (CAs) Keys of CAs are keys owned by a whole organization and not by an individual. Usually the fingerprints of those keys have to be verified by getting them from the corresponding website of the CA and cannot be checked by the Identity Verification procedures described below. If a viable procedure for verifying the \u0026lsquo;identity\u0026rsquo; of a CA\u0026rsquo;s keys is made known to me, I will add procedures for keys of CAs to the Identity Verification section. Until then, I will not sign keys owned by CAs.\nPrerequisites for Signing Identity Verification The signee must prove their identity to me by way of a national ID card, a driver\u0026rsquo;s license, or a similar identity document. The identity document must feature a photographic picture of the signee. This also implies that the signee\u0026rsquo;s key must feature their real name.\nIn addition, the signee must provide a secondary form of identification that includes their name, with or without a picture. Acceptable examples include, but are not limited to, a business card, a conference badge, a credit card, or an additional identity document as defined in the last paragraph.\nHardcopy of Fingerprint The signee should have prepared a printout of the output of gpg --fingerprint for their key (or the equivalent command of their OpenPGP client). I will keep this copy for reference.\nA hand-written sheet featuring the key ID, the fingerprint, and all user IDs the signee wishes to obtain a signature to will also be accepted.\nIf the signee wishes to obtain a signature to a photographic user ID, the printout should contain the image of that photographic user ID. A printout or photocopy of a photo clearly showing the same person as in the photographic user ID will also be accepted.\nMiscellaneous  The above must take place under reasonable circumstances, i.e. at a calm place, both parties not being in a hurry, etc. The signee should make their public key available on a publicly accessible pgp.net keyserver, such as hkps.pool.sks-keyservers.net, through Web Key Directory, or through Keybase. The signee should be willing to cross-sign with me.  The Act of Signing Fingerprint Verification At a secure location I will verify the key\u0026rsquo;s fingerprint using the hardcopy of the fingerprint that has been given to me.\nE-Mail Verification After successful fingerprint verification, I will sign all user IDs which I was asked to sign. Each signature is then individually sent to the email address listed in the corresponding user ID, enciphered to the signee\u0026rsquo;s key.\nAs only the signee can decipher and thus publish the signatures, it is warranted that the email addresses listed in each user ID with a published signature belongs to the signee.\n","id":"/signing-policy/","summary":"Do you want me to sign your key? Here\u0026rsquo;s how to do it!","tag":"","title":"OpenPGP Key Signing Policy","type":"signing-policy"},{"content":"After some thought, I replaced the .pushState() to .replaceState() in my infinite scroll implementation. This works more like people would expect, plus removes having to deal with the Back button.\n","id":"/notes/changed-infinite-scroll-to-replace-history/","summary":"After some thought, I replaced the .pushState() to .replaceState() in my infinite scroll implementation. This works more like people would expect, plus removes having to deal with the Back button.","tag":"devlog webdesign history ","title":"Changed Infinite Scroll to Replace History","type":"notes"},{"content":"I\u0026rsquo;m unsure why it took me so long, but I finally added the Bridgy target URLs to my posts. This should facilitate easier syndication to other social networks, though only for Twitter and Mastodon for now.\n","id":"/notes/added-bridgy-webmention-links/","summary":"I\u0026rsquo;m unsure why it took me so long, but I finally added the Bridgy target URLs to my posts. This should facilitate easier syndication to other social networks, though only for Twitter and Mastodon for now.","tag":"devlog bridgy webmentions mastodon twitter webdesign ","title":"Added Bridgy Webmention Links","type":"notes"},{"content":"  This Work is Public Domain!\nTo the extent possible under law, I waive all copyright and related or neighboring rights of this work by publishing it under the CC0 1.0 Universal Public Domain Dedication.\n  As my website\u0026rsquo;s content grows, Hugo\u0026rsquo;s list pages will grow as well. Without pagination, the list items in my site\u0026rsquo;s section and tag list pages would keep growing, thus increasing in size. In effect, a visit to any of my site\u0026rsquo;s list pages will essentially download every piece of content I\u0026rsquo;ve published if pagination wasn\u0026rsquo;t used.\nHowever, I\u0026rsquo;ve desired my site\u0026rsquo;s presentation to mimic a social media timeline, and a traditional paginated site\u0026ndash;with navigation buttons\u0026ndash;breaks that mimicry. Infinite scrolling has many consequences for usability; unusable footers and breaking the history are just two of the potential problems that may arise. Despite the potential downsides, I’ve determined that infinite scrolling makes sense for my site and decided to implement it.\nGoals  Keep things small and simple Utilize Hugo\u0026rsquo;s Pagination support The site should gracefully degrade when JavaScript is unavailable Use vanilla JavaScript Minimize the downsides  Steps Taken I\u0026rsquo;ve already fleshed out much of the JavaScript thought process in Thoughts on Infinte Scroll Pagination. Much of what was left is to actually make the code work and to just finish the implementation.\nPaginate the Homepage and List Pages While Mike Roibu opted to use Hugo\u0026rsquo;s Pagination support but iterated over the entire range in Infinite Scrolling Pagination in Hugo Website, I\u0026rsquo;ve decided to just use Hugo\u0026rsquo;s Pagination by default, but utilize customized navigation instead of the provided internal template.\nAs such, how I\u0026rsquo;ve utilize Hugo\u0026rsquo;s Pagination is basically as described from their website:\n\u0026lt;!-- Create the paginator before it\u0026#39;s used --\u0026gt; {{- $paginator := .Paginate .Site.RegularPages -}} \u0026lt;!-- Previous page link; hide if there is no previous page --\u0026gt; {{- if .Paginator.HasPrev -}} \u0026lt;a class=\u0026#34;paginator-previous-page\u0026#34; href=\u0026#34;{{ .Paginator.Prev.URL }}\u0026#34;\u0026gt;Previous\u0026lt;/a\u0026gt; {{- end -}} \u0026lt;!-- Iterate over all pages --\u0026gt; \u0026lt;div class=\u0026#34;all-entries\u0026#34;\u0026gt; {{- range $paginator.Pages -}} \u0026lt;!-- Do however you wish to display individual pages --\u0026gt; {{ end }} \u0026lt;/div\u0026gt; \u0026lt;!-- Next page link; hide if there is no next page --\u0026gt; {{- if .Paginator.HasNext -}} \u0026lt;a class=\u0026#34;paginator-next-page\u0026#34; href=\u0026#34;{{ .Paginator.Next.URL }}\u0026#34;\u0026gt;Next\u0026lt;/a\u0026gt; {{- end -}} Implement the Fetch in JavaScript Without JavaScript, the website provides paginated pages of list items that users may navigate through by using the Previous and Next anchors, if present on the page. What JavaScript needs to accomplish, then, is to fetch the next page and append the new list items to the bottom of the current page. I used the Fetch API for this purpose:\nasync function loadNextListPage() { let currentPagePaginationContainer = document.querySelector(\u0026#34;.all-entries\u0026#34;); let currentPageNextLink = document.querySelector(\u0026#34;.paginator-next-page\u0026#34;); let nextPage = currentPageNextLink.getAttribute(\u0026#34;href\u0026#34;); /* Try to get the next page asynchronously */ console.log(\u0026#34;pagination: Fetching next page...\u0026#34;); try { let response = await fetch(nextPage); if (response.ok) { let data = await response.text(); console.log(\u0026#34;pagination: Next page fetched!\u0026#34;); /* Get the new Pagination items of the next page and append */ let parser = new DOMParser(); let nextPageDom = parser.parseFromString(data, \u0026#34;text/html\u0026#34;); console.log(\u0026#34;pagination: Data parsed into temporary DOM!\u0026#34;); let newPaginatorItems = nextPageDom.querySelector(\u0026#34;.all-entries\u0026#34;).children; newPaginatorItems[0].removeAttribute(\u0026#34;open\u0026#34;); for (i = 0; i \u0026lt; newPaginatorItems.length; i++) { currentPagePaginationContainer.append(newPaginatorItems[i].cloneNode(true)); } console.log(\u0026#34;pagination: New items added!\u0026#34;); /* Update the history to the last page loaded */ let state = { \u0026#34;status\u0026#34;: \u0026#34;pagination: New list items added\u0026#34;, \u0026#34;previousPage\u0026#34;: window.location.pathname + window.location.search, \u0026#34;currentPage\u0026#34;: nextPage }; history.pushState(state, \u0026#34;\u0026#34;, nextPage); console.log(\u0026#34;pagination: New history pushed - \u0026#34;, state); /* Update the next page link on the current page */ let newNextLink = nextPageDom.querySelector(\u0026#34;.paginator-next-page\u0026#34;); if (newNextLink) { // When there is no next page, newNextLink is \u0026#39;null\u0026#39;  currentPageNextLink.setAttribute(\u0026#34;href\u0026#34;, newNextLink.getAttribute(\u0026#34;href\u0026#34;)); console.log(\u0026#34;pagination: Updated next page link!\u0026#34;); } else { // When there are no other pages, remove the next page link  if (currentPageNextLink.parentNode) currentPageNextLink.parentNode.removeChild(currentPageNextLink); console.log(\u0026#34;pagination: Removed next page anchor!\u0026#34;); } } else throw \u0026#34;response.ok was unsuccessful with status \u0026#39;\u0026#34; + response.statusText + \u0026#34; (\u0026#34; + response.status + \u0026#34;)\u0026#39;\u0026#34;; } catch (error) { /* A fetch() promise will reject with a TypeError when a network error is encountered or CORS is misconfigured on the server-side, although this usually means permission issues or similar — a 404 does not constitute a network error, for example. There are two places where awaited Promises may happen (and, ergo, will reject and throw an exception): the actual fetching of the next page and reading the response stream and converting it into a string. Considering a network error would preclude any access to my site and CORS is not utilized, any errors should, essentially, fall out of scope. I am not 100% certain when reading the response stream may fail. However, if something does throw an exception, I should know about it. In addition, this function will throw an exception if the Promises from the Fetch API still resolve, but the response was considered unsuccessful (status not in range of 200-299). I am not 100% certain what would cause an unsuccessful status with consideration of how my site is currently maintained and generated. However, should the Fetch\u0026#39;s API return an unsuccessful response for any reason, I also want to know about it.*/ console.error(\u0026#34;pagination: Caught a Fetch API exception! - \u0026#34;, error); } }  Update June 21, 2021: Instead of appending the page items from the next page, the code above appends a clone of the item. Originally, I was appending the items without cloning, but doing so changes newPaginatorItems.length which screws up a loop. Thank you very much for the person who emailed me that that was happening so I can make this change.\nIn practice, when this function is run, it downloads the next page, much like how a user would download the next page when clicking the Next anchor. The download cost without JavaScript and with JavaScript are the same, which makes this method download a bit more than implementations that can just request only the new items. Where it differs is once the next page is downloaded, instead of loading the next page the function parses it through a DOMParser which returns a Document. From there, standard DOM manipulation functions append the new items to the current page.\nAs I\u0026rsquo;ve commented, there are four situations where the fetching will fail and content won\u0026rsquo;t load: a network error, misconfigured Cross-Origin Resource Sharing (CORS), something happens reading the response stream, or the Promise resolves but the response was unsuccessful. In each of those situations none of them should affect my site\u0026ndash;mainly because if there is a network error my site would not be accessible in the first place. Put another way, I\u0026rsquo;m not confident on what exceptions I may realistically encounter that I will need to catch. Right now, all it does is catch any errors and report them in the console.\nUpdate the Next Page Link and the History You\u0026rsquo;ll notice in the function that once the new items have been appended to the current page, the current next page link is updated with the next next page and the history is updated using the History API:\n/* Update the history to the last page loaded */ let state = { \u0026#34;status\u0026#34;: \u0026#34;pagination: New list items added\u0026#34;, \u0026#34;previousPage\u0026#34;: window.location.pathname + window.location.search, \u0026#34;currentPage\u0026#34;: nextPage }; history.pushState(state, \u0026#34;\u0026#34;, nextPage); console.log(\u0026#34;pagination: New history pushed - \u0026#34;, state); /* Update the next page link on the current page */ let newNextLink = nextPageDom.querySelector(\u0026#34;.paginator-next-page\u0026#34;); if (newNextLink) { // When there is no next page, newNextLink is \u0026#39;null\u0026#39;  currentPageNextLink.setAttribute(\u0026#34;href\u0026#34;, newNextLink.getAttribute(\u0026#34;href\u0026#34;)); console.log(\u0026#34;pagination: Updated next page link!\u0026#34;); } else { // When there are no other pages, remove the next page link  if (currentPageNextLink.parentNode) currentPageNextLink.parentNode.removeChild(currentPageNextLink); console.log(\u0026#34;pagination: Removed next page anchor!\u0026#34;); }  To update the Next anchor to the next page\u0026rsquo;s link, I just replaced the current href attribute with the attribute in the downloaded page. The history\u0026ndash;again, using the History API\u0026ndash;was updated using history.pushState(). This adds the pages downloaded by the function to the session history. Alone, this does not reload the page whenever the user presses Back on their web browser. More later on will basically bring the expected behavior back to as close as possible.\nCall loadNextListPage() on Next Anchor\u0026rsquo;s onclick Right now, loadNextListPage() is created but nothing is calling it; as such, the page is still functioning as a traditional paginated experience. The first thing needed is for the function to be called whenever a User presses the Next anchor. I don\u0026rsquo;t call the function directly, however. Instead, I use two functions:\n/* Add onclick to \u0026#39;.paginator-next-page\u0026#39; if Fetch API is available */ function checkForFetchSupport() { if ((\u0026#34;fetch\u0026#34; in window) \u0026amp;\u0026amp; (document.querySelector(\u0026#34;.paginator-next-page\u0026#34;))) { console.log(\u0026#34;pagination: Fetch API available\u0026#34;); document.querySelector(\u0026#34;.paginator-next-page\u0026#34;).setAttribute(\u0026#34;onclick\u0026#34;, \u0026#34;manuallyLoadNextPage();\u0026#34;); } } addLoadEvent(checkForFetchSupport); /* The onclick event for \u0026#39;.paginator-next-page\u0026#39; */ function manuallyLoadNextPage() { event.preventDefault(); // Disable the default href click event  loadNextListPage(); }  The first function checks to see if the Fetch API is available in the user\u0026rsquo;s browser. From there, using principles of Unobtrusive JavaScript, it programmatically adds manuallyLoadNextPage()\u0026quot; to the Next anchor as an onclick event. Adding the onclick event in this manner means that the button will only call the function if the Fetch API is available and will fall back to loading the next page traditionally if clicked.\nYou\u0026rsquo;ll note that I\u0026rsquo;m using addLoadEvent(). This came from Lee Underwood\u0026rsquo;s Using Multiple JavaScript Onload Functions. I want it to check for the availability of the Fetch API and add the onclick event only once the page loads.\nThe reason for using manuallyLoadNextPage() instead of calling loadNextListPage() directly is so that the default event for an anchor can be disabled. Otherwise, when clicking the Next anchor, it will load the next page traditionally instead of handling the onclick event.\nUse IntersectionObserver to Call loadNextListPage() To review, at this point I\u0026rsquo;ve utilized Hugo\u0026rsquo;s Pagination to paginate the page as a graceful degration and programmatically added an onclick event on the Next anchor to manually load the next items into the page. To actually implement the infinite scrolling behavior, I utilize the power of the Intersection Observer API to call loadNextListPage() once something (in this case, my footer), becomes visible on the screen:\n/* Use the Intersection Observer API to get new items when scrolled down */ function observeForInfiniteScroll() { let nextPageObserver = new IntersectionObserver((entries, observer) =\u0026gt; { /* This is the callback function */ let firstEntry = entries[0]; // I\u0026#39;m not using multiple thresholds, so 0 suffices  if (firstEntry.isIntersecting) { // Basically if the footer is in view, run  if (!document.querySelector(\u0026#34;.paginator-next-page\u0026#34;)) { observer.disconnect(); // Stop the observer when there\u0026#39;s no more pages  console.log(\u0026#34;pagination: IntersectionObserver disconnected!\u0026#34;); } else loadNextListPage(); } }, { rootMargin: \u0026#34;0px 0px 80px 0px\u0026#34; }); nextPageObserver.observe(document.querySelector(\u0026#34;.icon-attribution\u0026#34;)); } if ((\u0026#34;IntersectionObserver\u0026#34; in window) \u0026amp;\u0026amp; (\u0026#34;fetch\u0026#34; in window)) { console.log(\u0026#34;pagination: IntersectionObserver and Fetch API available\u0026#34;) addLoadEvent(observeForInfiniteScroll); }  The constructor for IntersectionObserver takes two arguments: a callback function (I used an anonymous function, here) and an options object (I added an option to basically trigger the callback once the footer is 80 pixels away from the viewable area of the screen). Once you\u0026rsquo;ve given both of those, just call .observe() with the element that you wish the observer to watch for.\nLike the code above, I\u0026rsquo;m checking to see if both the Intersection Observer API and the Fetch API is available in the user\u0026rsquo;s browser. If they are, I\u0026rsquo;m using addLoadEvent() to call the function once the page fully loads.\nNow that this is complete, infinite scroll is finally implemented. You\u0026rsquo;ll notice as you scroll, once it gets to a certain point, the callback will be called and new items will be appended to the current page. This behavior will continue until it gets to the last page (signaled when the Next anchor is removed), at which point the Intersection Observer will disconnect and stop observing my footer. The implementation is finished, but there\u0026rsquo;s still one thing to tidy up.\nFixing the Back Button When you scroll through any list page on my site, go anywhere else (like to see a full post or to a different site altogether), then press back, the last page will be loaded for you. For example, if you started from page 1, loaded page 2, went somerwhere else, then went back; the browser will load\u0026ndash;essentially start\u0026ndash;from page 2. If you keep pressing Back, however, it will not load the previous entries; it will just pop through all the history states that were made when I used history.pushState() to update the history.\nTo mitigate this problem, I\u0026rsquo;ve added this to my JavaScript:\n/* When a \u0026#39;popstate\u0026#39; event triggers--like pressing the Back Button--reload the page. Do note that this isn\u0026#39;t particularly ideal, in my opinion, but it\u0026#39;s better than what would happen without it--the history state updating without actually reloading the page, thus causing posts to potentially not be there. However, in the context of social media using, the likelihood of scrolling up after scrolling down is, in my opinion, unlikely as a use case. */ window.onpopstate = function(event) { document.querySelector(\u0026#34;.all-entries\u0026#34;).scrollIntoView(true); history.go(); console.log(\u0026#34;pagination: Previous page loaded!\u0026#34;); }  Do note that this is not ideal; it breaks what a user expects to happen with the Back button because instead of going back to whatever the user was viewing before getting to my pages, the browser will go back and reload the previous pages that were called. Essentially they\u0026rsquo;ve never clicked on the Next anchor to view more content (because it was essentially done automatically), but they still have to click Back as many pages as they \u0026lsquo;viewed.\u0026rsquo;\nHowever, I feel this is better behavior than doing nothing, thus having nothing but the address bar updating happen when the user presses the Back button.\nFinal Thoughts While the Back button behavior is (somewhat) mitigated, there are still other problems that are endemic to all infinite scroll implementations: no way to return to the same position (my mitigation with the Back button doesn\u0026rsquo;t fix that at all), the scrollbar becomes useless, the footer also becomes useless, potential slowdown due to browser memory use once things get really large, and other problems. However, as I am presenting my site much like a social media timeline feed, I think infinite scroll is an appropriate way to display a summary of my posts.\nThe nice thing is if I don\u0026rsquo;t want to use infinite scrolling anymore (or if I\u0026rsquo;m persuaded to not use it anymore), I simply have to remove the IntersectionObserver or the entirety of the JavaScript. That will leave me back to a traditionally paginated list page, using just Hugo\u0026rsquo;s Pagination feature.\nAll in all, I\u0026rsquo;m pretty pleased with how this turned out. I get the consequences of implementing infinite scrolling and I feel like I\u0026rsquo;m making good decisions, but I\u0026rsquo;m relieved that should I want to reverse it, it\u0026rsquo;ll be easy.\n","id":"/articles/infinite-scrolling-on-hugo-list-pages/","summary":"Despite the potential downsides, I\u0026rsquo;ve determined that infinite scrolling makes sense for my site and decided to implement it.","tag":"devlog webdesign hugo javascript fetch history intersectionobserver ","title":"Infinite Scrolling on Hugo List Pages","type":"articles"},{"content":"Starting flight data entry for my flights posts. Just finished the YAML files for all the aircraft I\u0026rsquo;ve ridden. What\u0026rsquo;s left: 10 airlines, 87 airports, and finally typing in all my actual flights over the years. Woof\u0026hellip;\n","id":"/notes/starting-flight-data-entry/","summary":"Starting flight data entry for my flights posts. Just finished the YAML files for all the aircraft I\u0026rsquo;ve ridden. What\u0026rsquo;s left: 10 airlines, 87 airports, and finally typing in all my actual flights over the years. Woof\u0026hellip;","tag":"webdesign flights devlog ","title":"Starting Flight Data Entry","type":"notes"},{"content":"Fixed my CC0 shortcode, my flight maps, and the code highlighting. Thankfully it was all easy and relatively painless: the code highlighting and shortcodes was just a change of how to write it in, while the flight maps was just a matter of updating the URL to the current Leaflet tutorials.\n","id":"/notes/fixed-shortcodes-code-and-maps/","summary":"Fixed my CC0 shortcode, my flight maps, and the code highlighting. Thankfully it was all easy and relatively painless: the code highlighting and shortcodes was just a change of how to write it in, while the flight maps was just a matter of updating the URL to the current Leaflet tutorials.","tag":"devlog webdesign ","title":"Fixed Shortcodes, Code, and Maps","type":"notes"},{"content":"Huh, some things broke on my site. The particular things that are going wonky are some of the code styling in some posts with code, my CC0 shortcode, and my flight maps using Leaflet. I need to fix that.\n","id":"/notes/huh-some-things-broke/","summary":"Huh, some things broke on my site. The particular things that are going wonky are some of the code styling in some posts with code, my CC0 shortcode, and my flight maps using Leaflet. I need to fix that.","tag":"devlog webdesign problems ","title":"Huh, Some Things Broke","type":"notes"},{"content":"  This Work is Public Domain!\nTo the extent possible under law, I waive all copyright and related or neighboring rights of this work by publishing it under the CC0 1.0 Universal Public Domain Dedication.\n  I’ve looked over Mike Roibu’s post, Infinite Scrolling Pagination in Hugo Website. More or less I like the idea of it, and I’m trying to flesh out an idea for how I want to paginate for my site.\nThe first idea I\u0026rsquo;d like to play around with is instead of having each page in the Paginator have the page items in the previous pages, I think I\u0026rsquo;m going to play around with only having the pages on that page in there. It\u0026rsquo;s true that by using JavaScript it still ends up downloading a whole new page in practice, but then I could just do something like:\n(async () =\u0026gt; { /* Set some stuff up */ let currentPagePaginationContainer = document.querySelector(\u0026#34;.all-entries\u0026#34;); let currentPageNextLink = document.querySelector(\u0026#34;.next-page\u0026#34;); let nextPage = currentPageNextLink.getAttribute(\u0026#34;href\u0026#34;); let nextPageDom = document.createElement(\u0026#34;template\u0026#34;); /* Get the next page asynchronously */ console.log(\u0026#34;pagination: Fetching next page...\u0026#34;) let response = await fetch(nextPage); let data = await response.text(); console.log(\u0026#34;pagination: Next page fetched!\u0026#34;); /* Get the new Pagination items of the next page and append */ nextPageDom.innerHTML = data; let newPaginatorItems = nextPageDom.querySelector(\u0026#34;.all-entries\u0026#34;).content; currentPagePaginationContainer.appendChild(newPaginatorItems); console.log(\u0026#34;pagination: New items added!\u0026#34;); /* Update the next page link on the current page */ let newNextLink = nextPageDom.querySelector(\u0026#34;.next-page\u0026#34;).getAttribute(\u0026#34;href\u0026#34;); currentPageNextLink.setAttribute(\u0026#34;href\u0026#34;, newNextLink); console.log(\u0026#34;pagination: Updated next page link!\u0026#34;); /* TODO: Update history so that forward/back works correctly */ /* TODO: Disable/Override the next page link to load more page items */ /* TODO: Use the Intersection Observer API to get new items */ })();  Some thoughts, though, while I was thinking this kinda dirty code that I don\u0026rsquo;t know works is that should a user press Back they\u0026rsquo;ll be sent back to the previous page. Which would normally be okay, but if they got to their last page by clicking on an item that was added, that item would, understandably, not be there. Or, more specifically, if the history is updated, they\u0026rsquo;ll get to a page where the item is there, but items before it may not be there and would require further pressing of back. Perhaps Mike\u0026rsquo;s method of having all items on a page would be better for site visitors. This requires a bit more thought, but I don\u0026rsquo;t like the idea of downloading more than is needed.\nAlso, implied, I\u0026rsquo;d like to try doing this using vanilla JavaScript to tackle one of his post\u0026rsquo;s proposed improvements.\n","id":"/articles/thoughts-on-infinite-scroll-pagination/","summary":"I\u0026rsquo;ve looked over Mike Roibu\u0026rsquo;s post, Infinite Scrolling Pagination in Hugo Website. More or less I like the idea of it, and I\u0026rsquo;m trying to flesh out an idea for how I want to paginate for my site.","tag":"devlog webdesign hugo javascript ","title":"Thoughts on Infinite Scroll Pagination","type":"articles"},{"content":"  This Work is Public Domain!\nTo the extent possible under law, I waive all copyright and related or neighboring rights of this work by publishing it under the CC0 1.0 Universal Public Domain Dedication.\n  My site isn\u0026rsquo;t that old, but slowly and surely I\u0026rsquo;ve been working on bits and pieces to make a working website that has all the features people expect. Because I\u0026rsquo;m running a static site that\u0026rsquo;s built by Hugo, I didn\u0026rsquo;t think that there would be an option for me to have my own search, so I utilized DuckDuckGo to search my site along with some JavaScript that added site:sentamal.in to any query so it only displayed my site\u0026rsquo;s results.\nWhile using DuckDuckGo worked, it wasn\u0026rsquo;t ideal; I\u0026rsquo;d be at the mercy of a website\u0026rsquo;s crawlers to update their search results with my pages. I wanted to provide something that was more current for my visitors, so I searched for other options.\nHugo provides many search options for static sites on their page, which led me to Lunr. I searched for more blog posts about implementation, but none of them were satisfactory to me; many relied on other libraries that I didn’t want to add. So, I made my own!\nWhy Lunr? Well\u0026hellip; Partly because it was the most prominent example I could find while I was searching for a client-side static search. I wasn\u0026rsquo;t exactly sure what Solr referenced to (and I assumed it was Apache Solr), and ElastiSearch wasn\u0026rsquo;t free. After looking through all the documentation it also seemed like something I\u0026rsquo;d be able to implement using my current skills.\nGoals  Minimalist; few or no other dependencies Fast; a search result should appear quickly Small; keep downloads and device processing small Use ?q= queries; allows for sitelink searches in SERPs  Step 1: Create the Document JSON Lunr relies on an array of documents formatted in JSON to build its index. Thankfully, Hugo\u0026rsquo;s dict and jsonify functions and its ability to create custom output formats made it easy to build the relevant arrays for Lunr to use.\nDocument Archetype (JSON) { \u0026#34;id\u0026#34;: \u0026#34;https://some.url/\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Page Title\u0026#34;, \u0026#34;tag\u0026#34;: \u0026#34;some tags\u0026#34;, \u0026#34;summary\u0026#34;: \u0026#34;A summary of the page\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;The page\u0026#39;s full text content\u0026#34; }\nTo actually have Hugo generate the JSON, I created two new pages in my /content directory: lunr-full.md and lunr-summary.md. Note that Lunr only needs one source of documents, and I\u0026rsquo;m only using lunr-full.md for the index build. However, when Lunr returns search results, it only returns an array of objects that only has a reference to the page. Lunr does not return things like the page\u0026rsquo;s title or summary and requires getting that information from \u0026ldquo;somewhere else\u0026rdquo;. lunr-summary.md provides that \u0026ldquo;somewhere else.\u0026rdquo; Note that the only thing in these files is front matter.\nlunr-full.md (Markdown/YAML) --- date: 2018-05-06T03:31:00-06:00 type: search layout: full url: /search/lunr-full.json outputs: - json ---\nlunr-summary.md (Markdown/YAML) --- date: 2018-05-06T03:31:00-06:00 type: search layout: summary url: /search/lunr-summary.json outputs: - json ---\n(I have to admit that there\u0026rsquo;s something a little hacky I did with the dates in these pages. When I first made these I omitted a date parameter, but it was screwing up the JSON creation in that it wasn\u0026rsquo;t adding commas between documents. I changed the date to a time in the past to mitigate that.)\nAfter making these files, I made /layouts/search/full.json and /layouts/search/summary.json. It took me a little bit of reading through Hugo docs to figure this out, but because of the type choices and output choices in the front matter, Hugo will look for a suitable template in /layouts/[type]/[layout].[output]. The only difference between one and the other is the full document (used for actually building the Lunr index) includes the document\u0026rsquo;s type, tags, and content.\nfull.json (Go Template/Hugo) [{{- range where .Site.RegularPages \u0026#34;Type\u0026#34; \u0026#34;ne\u0026#34; \u0026#34;search\u0026#34; -}} {{- $scratch := newScratch -}} {{- $scratch.Set \u0026#34;tags\u0026#34; \u0026#34;\u0026#34; -}} {{- range .Params.tags -}} {{- $scratch.Add \u0026#34;tags\u0026#34; . -}} {{- $scratch.Add \u0026#34;tags\u0026#34; \u0026#34; \u0026#34; -}} {{- end -}} {{- dict \u0026#34;id\u0026#34; (.Permalink | relURL) \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;tag\u0026#34; ($scratch.Get \u0026#34;tags\u0026#34;) \u0026#34;summary\u0026#34; (.Summary | plainify) \u0026#34;content\u0026#34; .Plain | jsonify -}} {{- if .Prev -}},{{- end -}} {{- end -}}]\nsummary.json (Go Template/Hugo) [{{- range where .Site.RegularPages \u0026#34;Type\u0026#34; \u0026#34;ne\u0026#34; \u0026#34;search\u0026#34; -}} {{- dict \u0026#34;id\u0026#34; (.Permalink | relURL) \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;summary\u0026#34; (.Summary | plainify) | jsonify -}} {{- if .Prev -}},{{- end -}} {{- end -}}]\nWith these files made, a lunr-full.json and a lunr-summary.json will be created in /public/search whenever hugo is run. To save a step, these files are already minified to boot!\nStep 2: Pre-Build the Lunr Index Lunr\u0026rsquo;s documentation recommends pre-building the index, especially for \u0026ldquo;large indexes or with documents that are largely static, such as a static site.\u0026rdquo; This is to prevent blocking the browser while the index builds.\nFor this I used their documentation verbatim to create a Node.js script that builds an index from my full document array made earlier.\nFrom there it was a matter of running cat /path/to/lunr-full.json | node /path/to/build-index.js \u0026gt; public/search/lunr-index.json after running hugo to add the pre-built index to my static site.\nStep 3: Create the Search Page With the index made and a document summary available, it\u0026rsquo;s just a matter of linking it all together. I decided to make the search page first because the JavaScript was the most daunting part of all of this. I made /content/search/index.md and /layouts/search/index.html to begin this process. For brevity I\u0026rsquo;ve written the HTML below to the bare minimum for understanding. Of course you can modify the template to suit your needs.\nindex.md (Markdown/YAML) --- title: \u0026#34;Search\u0026#34; date: 2020-01-02T16:05:06-06:00 type: search layout: index draft: false ---\nindex.html (Go Template/Hugo) \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Search\u0026lt;/title\u0026gt; \u0026lt;script src=\u0026#34;https://unpkg.com/lunr/lunr.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;/scripts/page-search.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;div id=\u0026#34;search-results\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;template id=\u0026#34;search-item\u0026#34;\u0026gt; \u0026lt;article\u0026gt; \u0026lt;h1\u0026gt;\u0026lt;a\u0026gt;\u0026lt;/a\u0026gt;\u0026lt;/h1\u0026gt; \u0026lt;aside\u0026gt;\u0026lt;/aside\u0026gt; \u0026lt;p\u0026gt;\u0026lt;/p\u0026gt; \u0026lt;/article\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt;\nNote that I\u0026rsquo;m using \u0026lt;template\u0026gt; as the markup I\u0026rsquo;ll be using to, well, mark up found search results.\nStep 4: Write the Rest of the Code This took a bit of reading for me to actually do correctly. I knew about XHR, but I also knew about the Fetch API. I also knew that the latter was a bit easier to implement and to read.\nWhat I didn\u0026rsquo;t know initially was I could use async and await, which were things I\u0026rsquo;m more accustomed to when I was working in C#. I ended up with a bit of a hellish glob of callbacks doing it the other way, but once I figured out I could just use async it made things a lot easier for me to read (and understand, and write).\npage-search.js (JavaScript) /* Async Function to Start LunrJS */ async function startLunrJSAsync() { console.log(\u0026#34;search: Starting Lunr...\u0026#34;); let idx, pages; let ok = false; const lunrIndex = \u0026#34;lunr-index.json\u0026#34;; const lunrSummary = \u0026#34;lunr-summary.json\u0026#34;; /* Load the Pre-Built Index */ console.log(\u0026#34;search: Fetching Index...\u0026#34;); let response = await fetch(lunrIndex); let data = await response.json(); idx = lunr.Index.load(data); console.log(\u0026#34;search: Index Loaded!\u0026#34;); /* Load the Page Summaries */ console.log(\u0026#34;search: Fetching Summaries...\u0026#34;); response = await fetch(lunrSummary); data = await response.json(); pages = data; console.log(\u0026#34;search: Summaries Loaded!\u0026#34;); /* Lunr is Ready; Return */ console.log(\u0026#34;search: Lunr Is Ready!\u0026#34;); ok = true; let obj = { idx: idx, pages: pages, ok: ok }; return obj; } /* Clear the Search Results element then populate with search results */ function searchSite(search, query) { let template = document.querySelector(\u0026#34;#search-item\u0026#34;); let resultsContainer = document.querySelector(\u0026#34;#search-results\u0026#34;); resultsContainer.innerHTML = \u0026#34;\u0026#34;; let allResults = search.idx.search(query); if (allResults.length === 0) resultsContainer.innerHTML = \u0026#34;\u0026lt;p\u0026gt;Nothing found; search for something else!\u0026lt;/p\u0026gt;\u0026#34;; else allResults.forEach(function (result) { let output = document.importNode(template.content, true); let title = output.querySelector(\u0026#34;a\u0026#34;); let breadcrumb = output.querySelector(\u0026#34;aside\u0026#34;); let summary = output.querySelector(\u0026#34;p\u0026#34;); let docRef, typemoji; /* Find the requisite document summary for the search result */ for (let i=0; i \u0026lt; search.pages.length; i++) { if (search.pages[i].id === result.ref) { docRef = search.pages[i]; break; } } title.innerHTML = docRef.title; title.setAttribute(\u0026#34;href\u0026#34;, result.ref); breadcrumb.innerHTML = \u0026#34;Don Geronimo » \u0026#34; + docRef.type.charAt(0).toUpperCase() + docRef.type.slice(1) + \u0026#34; » \u0026#34; + docRef.title; summary.innerHTML = docRef.summary; resultsContainer.appendChild(output); }); } (async () =\u0026gt; { /* Initialize Lunr */ let Search = await startLunrJSAsync(); /* If there is a query in the URL, use that as the search query */ let query; let params = new URLSearchParams(document.location.search.substring(1)); if (params.get(\u0026#34;q\u0026#34;)) { document.getElementById(\u0026#34;ddg-search-value\u0026#34;).value = params.get(\u0026#34;q\u0026#34;); query = params.get(\u0026#34;q\u0026#34;); searchSite(Search, query); } })(); \nThe last line lets people use my search page like literally any other search engine which can receive a query using a GET request. In practice no server processing is being made, but the client can parse through the URL to get the query.\nConsiderations with Client-Side Search After doing all this I ended up with a search service for my website all done on the client. However, that means that there is a danger that the index may eventually get too big. Right now, lunr-index.js is about 160 KB while lunr-summary.js is about 21 KB. The page itself is around 12 KB. Obviously other resources (like images, style sheets, the actual Lunr.js script, etc) will cause it to be bigger. It\u0026rsquo;s a managable size right now, but it can only grow larger the more posts exist.\nStill, it\u0026rsquo;s nice to provide a search function that may search better than a search engine. As things grow larger I can think of ways to better mitigate some of the problems of client-side search, but until then this is good enough for now.\n","id":"/articles/static-site-search-with-lunrjs/","summary":"Hugo provides many search options for static sites on their page, which led me to Lunr. I searched for more blog posts about implementation, but none of them were satisfactory to me; many relied on other libraries that I didn\u0026rsquo;t want to add. So, I made my own!","tag":"devlog search hugo lunrjs javascript json ","title":"Static Site Search With Lunr.js","type":"articles"},{"content":"Today I\u0026rsquo;ve been working on getting my site ready for its own search provider using Lunr.js, which provides search for visitors using client-side JavaScript. Hugo was easy enough to generate a JSON file thanks to dict and jsonify. The hard part was, well, everything else.\nThing is, this is a lot more JavaScript than I\u0026rsquo;m used to having to do. I\u0026rsquo;m thankful that I at least have a presentation finished up and that I\u0026rsquo;m generating valid JSON to (eventually) parse into Lunr.js, but the actual implementation feels daunting to me. I\u0026rsquo;m hoping it\u0026rsquo;ll actually be easy, though, once I start on it.\nBut I think, for now, placeholders that work, a proper template, and a proper source of data for search is enough. Next steps are to basically hook everything up (you know, to actually display a result when someone types a search in) and to pre-build the search index.\n","id":"/photos/doing-everything-but-javascript/","summary":"I worked on the HTML and CSS of the Search Results page instead of implementing the JavaScript part of Lunr.js. At least it looks okay? Everything else is left, though.","tag":"devlog webdesign search javascript hugo ","title":"Doing Everything but Javascript","type":"photos"},{"content":"Breadcrumbs added. I get it\u0026rsquo;s not that interesting of an addition, but there it is. Next goal: get my own search feature using probably Lunr.js.\n","id":"/notes/breadcrumbs-added/","summary":"Breadcrumbs added. I get it\u0026rsquo;s not that interesting of an addition, but there it is. Next goal: get my own search feature using probably Lunr.js.","tag":"devlog webdesign search ","title":"Breadcrumbs Added","type":"notes"},{"content":"Man, I like the idea of having the images on my site be lazy loaded, but I don\u0026rsquo;t like the idea of depending on JavaScript for it, or any of the ways to fall back at the moment if someone chooses (because of browser choices, privacy concerns, or what-have-them) to disable JavaScript.\n","id":"/notes/lazy-loading-woes/","summary":"Man, I like the idea of having the images on my site be lazy loaded, but I don\u0026rsquo;t like the idea of depending on JavaScript for it, or any of the ways to fall back at the moment if someone chooses (because of browser choices, privacy concerns, or what-have-them) to disable JavaScript.","tag":"webdesign javascript accessibility ","title":"Lazy Loading Woes","type":"notes"},{"content":"  This Work is Public Domain!\nTo the extent possible under law, I waive all copyright and related or neighboring rights of this work by publishing it under the CC0 1.0 Universal Public Domain Dedication.\n  Since getting my domain, I\u0026rsquo;ve been making efforts of putting what social media-y things I wanted to share on the Internet on that instead of using any other website or service if I can help it. For nearly everything else it was pretty easy since (aside from Scuttlebutt) I don\u0026rsquo;t really use any other social networks unless I\u0026rsquo;m directly messaging friends and other contacts. However, MyFlightradar24 is a different case. Having to import all my flights from it to another system is a cause of extreme inertia, and the data visualizations are too nice.\nStill, I\u0026rsquo;d like to put it on my site instead. So after some thought I finally have flights on my site!\nNearly Five Years of Flight Data Logged MyFlightradar24 is still a pretty cool way of logging my flight information. In addition, it also provides some really fun visualizations and statistics of my flights. I particularly liked seeing the total hours I\u0026rsquo;ve spent in a plane, the total amount of miles I\u0026rsquo;ve logged, and what my estimated emissions are. Its flight input is a bit annoying in that it\u0026rsquo;s multiple pages, but I stuck with it because there were very few other options that worked well.\n(As background, flight attendants, unlike pilots, don\u0026rsquo;t need to keep logs of the flights they work. So most things made for aviation professionals tailor to pilots and wasn\u0026rsquo;t exactly the kind of thing suited for my purposes.)\nIn addition, it\u0026rsquo;s essentially just a database that stores my flights and presents the data into a pretty format. This is something I can achieve on my own site and I wouldn\u0026rsquo;t have to worry about losing this functionality in the future.\nStarted with Data I started off with the data first, because in my head having a sense of how everything is structured makes its presentation so much easier. In Hugo I created a few new folders in the data folder for airports, airlines, and aircraft. In each of those folders I created (in YAML):\n{ICAO Type Code for Airline}.yaml = a19n.yaml --- name: Airbus A319neo ata: 31N ...\n{IATA Airline Code}.yaml = dl.yaml --- name: Delta Air Lines url: https://www.delta.com icao: DAL callsign: DELTA flight_class: first: Delta One/First Class business: Premium Select prem_econ: Comfort+ economy: Main Cabin ...\n{IATA Airport Code}.yaml = atl.yaml --- name: Hartsfield-Jackson Atlanta International Airport url: http://www.atl.com/ icao: KATL adr: street_address: 6000 North Terminal Parkway locality: Atlanta region: Georgia postal_code: \u0026#34;30320\u0026#34; country_name: United States geo: latitude: 33.6366996 longitude: -84.4278640 altitude: 312.8 ...\nAfter this, I worked on an archetype for flights posts (flights.md):\n--- title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; date: {{ .Date }} draft: true airline: # ATA, ICAO, Callsign, or Full Airline Name flight_number: # Flight number without the Airline Code departure_airport: # ATA or ICAO of airport departure_datetime: # Datetime should be local to the airport arrival_airport: # ATA or ICAO of airport arrival_datetime: # Datetime should be local to the airport flight_duration: # Duration in ISO8601: P[n]Y[n]M[n]DT[n]H[n]M[n]S aircraft_type: # ICAO (A20N), IATA Type (32N) or Aircraft Name (A320neo) aircraft_registration: # Like N720FR flight_class: # first, business, prem_econ, economy, or private flight_seat_type: # window, middle, or aisle flight_seat_number: # Like 13F flight_reason: # leisure, business, crew, or other --- Content goes here! From There it\u0026rsquo;s all Templates Providing data about an airline, aircraft, and airport; and providing such data in the front matter of each Flights post, makes it a matter of just calling up the right data into templates to make each entry. In my head it was easier to figure out what data was and where data was stored before I sorted out how to present it, and after I got a model in my head it was just an hour\u0026rsquo;s work of HTML, JavaScript, and some Go Templating to present my flight logs into a nice page.\nBecause of my current obsession with describing everything with RDFa, and also to harmonize with current efforts of the IndieWeb community (whose resources have helped immensely as a whole for my site), I\u0026rsquo;ve described my flights with the h-entry and h-event microformats and Schema.org\u0026rsquo;s BlogPosting and Flight definitions.\nThe previews of the flights are a static image provided by Mapbox\u0026rsquo;s static image service, while Leaflet provides an interactive map with the flight arc drawn thanks to Leaflet.Arc. OpenStreetMap provides the tile layers for the interactive map.\nRight now, I\u0026rsquo;ve also created some JavaScript that calculates distance using the Haversine formula, with a possible override of a literal distance of the flight in the front matter on a per-page basis. However, I am not currently using that until I figure out\u0026hellip;\nNext Goal: Data Visualization I\u0026rsquo;m currently displaying basic data on a per-flight basis, and presenting it in my site\u0026rsquo;s default list template. It works; it\u0026rsquo;s not ideal. More specifically, I currently don\u0026rsquo;t have all the data visualizations fleshed out yet\u0026ndash;particularly not in the amount that MyFlightradar24 has. I\u0026rsquo;m thinking that I\u0026rsquo;m going to want to use some sort of JavaScript library for data visualization, but I\u0026rsquo;ll need to figure out where said data should be stored. I\u0026rsquo;m using a Static Site and the place where I\u0026rsquo;m hosting does not provide server-side scripting, so I\u0026rsquo;m going to need to be creative. But before even that\u0026hellip;\nBefore Next Goal: Data Entry This is going to be a slog. Not only will I need to export my data from MyFlightradar24 and put them up as pages in my site, I will also need to input data of all the airports that I\u0026rsquo;ve flown into, all the planes I\u0026rsquo;ve ridden in, and all the airlines I\u0026rsquo;ve flown with! That\u0026rsquo;s going to be a ton of work at first, but once finished should make it easy to just using my site.\n(I should really consider if, perhaps, such a store of data on airports, airplanes, and airlines in YAML would be helpful for someone and if I should distribute it somewhere. Hm.)\nThis Is Enough For Now Even without getting to the next goal post, being able to own my flight data on my own site is a huge thing. Huge enough that I should be able to eventually just own and host everything I post on the Internet from now on.\n","id":"/articles/got-flights-added-to-my-website/","summary":"So after some thought I finally have flights on my site!","tag":"webdesign indieweb flights hugo yaml devlog rdfa schema microformats ","title":"Got Flights Added to My Website","type":"articles"},{"content":"RDFa Validator: Your nodes all check out!\nGoogle SDTT: So MaNy ErRoRs; YoU\u0026rsquo;rE a FaIlUrE!\nMe: *internal screaming*\n","id":"/notes/metadata-internal-screaming/","summary":"RDFa Validator: Your nodes all check out!\nGoogle SDTT: So MaNy ErRoRs; YoU\u0026rsquo;rE a FaIlUrE!\nMe: *internal screaming*","tag":"webdesign metadata google rdfa schema ","title":"Metadata Internal Screaming","type":"notes"},{"content":"After some tidying I\u0026rsquo;ve finished merging \u0026lsquo;flights\u0026rsquo; into my \u0026lsquo;master\u0026rsquo; branch, thus finishing an ability to post Flights from my website. While the initial presentation of data is sparse, this lays the groundwork to owning my flight data instead of relying on a third service to store and present it.\n","id":"/notes/merged-flights-into-master/","summary":"After some tidying I\u0026rsquo;ve finished merging \u0026lsquo;flights\u0026rsquo; into my \u0026lsquo;master\u0026rsquo; branch, thus finishing an ability to post Flights from my website. While the initial presentation of data is sparse, this lays the groundwork to owning my flight data instead of relying on a third service to store and present it.","tag":"devlog indieweb flights webdesign hugo ","title":"Merged Flights Into Master","type":"notes"},{"content":"","id":"/flights/worked-f91422-12dec2019/","summary":"","tag":"","title":"Worked F91422","type":"flights"},{"content":"","id":"/flights/worked-f91423-11dec2019/","summary":"","tag":"","title":"Worked F91423","type":"flights"},{"content":"","id":"/photos/finishing-up-single-page-flights/","summary":"After a bit of mucking about I\u0026rsquo;ve more-or-less finished the look I want to display Flights as a single-page template! I want to do some tweaks (and do some data transforms\u0026ndash;because who wants flight time in seconds), though.","tag":"devlog hugo flights indieweb webdesign ","title":"Finishing Up Single Page Flights","type":"photos"},{"content":"I saw this a while ago and wanted to make sure I captured liking this. It really resonates with me on how it\u0026rsquo;s like living as a flight crew member.\n","id":"/likes/long-term-parking/","summary":"I saw this a while ago and wanted to make sure I captured liking this. It really resonates with me on how it\u0026rsquo;s like living as a flight crew member.","tag":"aviation op-docs shortfilm ","title":"Long Term Parking","type":"likes"},{"content":"MyFlightradar24 is the only silo–if it can be counted as one–that I consistently use. Its presentation of my flight data is wonderful, but I feel like I could do it myself on my own site. Today, I’ve opened up my flights branch so I can finally sort out what I need to make this happen!\nWhy Do This? A lot of it is because I\u0026rsquo;d like to make sure that my flight data is owned by me and hosted by me. FlightRadar24 is actually an excellent service, in my opinion, and actually lets you export your data out easily from its platform. It also provides some nice data visualization.\nHowever, it\u0026rsquo;s not particularly interactive. People can\u0026rsquo;t really reply or react to your flights. You\u0026rsquo;re also stuck to the data visualizations they provide without any customization (that being said, a lot of its data visualization is exactly as I wanted and I don\u0026rsquo;t feel lacking, but in the future perhaps I want further control). I\u0026rsquo;d like to be able to visualize my data in new and various ways in the future, even if, at the start, my data presentation will not be as robust as the service.\nWhat I\u0026rsquo;ve Finished Thus Far I\u0026rsquo;ve catalogued my steps for Flight Logs on my IndieWeb userpage, but to start off with, I branched my current site and did the easy stuff first:\nCreate an Archetype in Hugo For Flights To create the Archetype, I essentially looked at the data input process that MyFlightradar24 asks for and created the YAML Front-Matter from that:\n--- title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; date: {{ .Date }} draft: true airline: # ATA, ICAO, Callsign, or Full Airline Name flight_number: # Flight number without the Airline Code departure_airport: # ATA or ICAO of airport departure_datetime: # Datetime should be local to the airport arrival_airport: # ATA or ICAO of airport arrival_datetime: # Datetime should be local to the airport flight_duration: # Number of seconds aircraft_type: # ICAO (A20N), IATA Type (32N) or Aircraft Name (A320neo) aircraft_registration: # Like N720FR flight_class: # first, business, prem_econ, economy, or private flight_seat_type: # window, middle, or aisle flight_seat_number: # Like 13F flight_reason: # leisure, business, crew, or other --- Personal notes, summaries, or anything else to describe this flight goes here. Hugo allows this section to be formatted _in Markdown_! Create new JSON in Data for Airlines, Airports, and Aircraft I don\u0026rsquo;t want to overload the Front Matter per-site, and I want to create less work for me. Airport, Airline, and Aircraft Type information doesn\u0026rsquo;t change or deviate often enough to require changes on a per-flight basis. I am also a little bit lazy. Ergo, separating information I may use often works well for saving me time and typing.\naircraft.json [ { \u0026#34;name\u0026#34;: \u0026#34;Airbus A319\u0026#34;, \u0026#34;ata\u0026#34;: \u0026#34;319\u0026#34;, \u0026#34;icao\u0026#34;: \u0026#34;A319\u0026#34; } ] airlines.json [ { \u0026#34;name\u0026#34;: \u0026#34;Frontier Airlines\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://flyfrontier.com\u0026#34;, \u0026#34;icao\u0026#34;: \u0026#34;fft\u0026#34;, \u0026#34;ata\u0026#34;: \u0026#34;f9\u0026#34;, \u0026#34;callsign\u0026#34;: \u0026#34;frontier flight\u0026#34;, \u0026#34;flight_class\u0026#34;: { \u0026#34;prem_econ\u0026#34;: \u0026#34;Stretch\u0026#34;, \u0026#34;economy\u0026#34;: \u0026#34;Economy\u0026#34; } } ] airports.json [ { \u0026#34;name\u0026#34;: \u0026#34;Chicago O\u0026#39;Hare International Airport\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://www.flychicago.com/ohare\u0026#34;, \u0026#34;ata\u0026#34;: \u0026#34;ord\u0026#34;, \u0026#34;icao\u0026#34;: \u0026#34;kord\u0026#34;, \u0026#34;adr\u0026#34;: { \u0026#34;street_address\u0026#34;: \u0026#34;10000 West O\u0026#39;Hare Avenue\u0026#34;, \u0026#34;locality\u0026#34;: \u0026#34;Chicago\u0026#34;, \u0026#34;region\u0026#34;: \u0026#34;Illinois\u0026#34;, \u0026#34;postal_code\u0026#34;: \u0026#34;60666\u0026#34;, \u0026#34;country_name\u0026#34;: \u0026#34;United States\u0026#34;, \u0026#34;geo\u0026#34;: { \u0026#34;latitude\u0026#34;: 41.978611, \u0026#34;longitude\u0026#34;: -87.904722, \u0026#34;altitude\u0026#34;: 207.3 } } } ] Next Steps Data collection is easy\u0026ndash;whether from me (inputting a flight log entry) or from the JSON (I\u0026rsquo;ll add airports, airlines, and aircraft as necessary). Actual presentation and templating will be the hard part here.\nSoon I\u0026rsquo;ll be starting out on the single flight template. I want to show off an interactive map that shows the flight from the departure point to the arrival point. Data like flight duration, departure and arrival times, nautical miles, and other data should also be presented as well. It\u0026rsquo;ll probably be good for me to see how other places (like FlightAware or Flightradar24) display flight information to get some structure and presentation ideas. Each single page should be formatted as an h-entry for the flight log entry itself with an h-event describing the flight.\nThe list page template should be fairly similar as well, building off what I\u0026rsquo;ve made in the single page template. However, I would like there to be a full interactive map of the world with all my flights on it.\nProjected Final Product What I should end up with after doing all this is a pretty simple map with a bunch of lines showing all the flights I\u0026rsquo;ve taken. While I won\u0026rsquo;t have all the data presented in MyFlightradar24 after all this, I should be able to keep working on different visualizations in the future to eventually get it just as good\u0026ndash;if not better\u0026ndash;than the Flightradar24 silo.\nHere\u0026rsquo;s hoping it goes well!\n","id":"/articles/starting-to-add-flight-logs/","summary":"MyFlightradar24 is the only silo\u0026ndash;if it can be counted as one\u0026ndash;that I consistently use. Its presentation of my flight data is wonderful, but I feel like I could do it myself on my own site. Today, I\u0026rsquo;ve opened up my flights branch so I can finally sort out what I need to make this happen!","tag":"devlog hugo webdesign flights json indieweb ","title":"Starting to Add Flight Logs","type":"articles"},{"content":"It\u0026rsquo;s almost been a week and I still get a Headache-Fever-Pain Triple Whammy. Thankfully it\u0026rsquo;s not like I can\u0026rsquo;t get anything done or work on things, but it makes focus so difficult. I cannot wait to actually feel normal again.\n","id":"/notes/sickness-triple-whammy/","summary":"It\u0026rsquo;s almost been a week and I still get a Headache-Fever-Pain Triple Whammy. Thankfully it\u0026rsquo;s not like I can\u0026rsquo;t get anything done or work on things, but it makes focus so difficult. I cannot wait to actually feel normal again.","tag":"sick ","title":"Sickness Triple Whammy","type":"notes"},{"content":"While the actual search bar functionally works, there were a few weird things going on that looks weird on Firefox. It still looks a bit odd on Firefox, too, as the bar and the contact icons start merging together. I\u0026rsquo;ll fix that later.\n","id":"/replies/search-bar-tweaks-for-firefox/","summary":"While the actual search bar functionally works, there were a few weird things going on that looks weird on Firefox. It still looks a bit odd on Firefox, too, as the bar and the contact icons start merging together. I\u0026rsquo;ll fix that later.","tag":"","title":"Search Bar Tweaks for Firefox","type":"replies"},{"content":"I\u0026rsquo;ve added a search bar to my site\u0026rsquo;s main navigation that\u0026rsquo;s powered by DuckDuckGo. Its styling doesn\u0026rsquo;t look quite right to me when on a desktop, though, and while it looks more at-home on mobile it also doesn\u0026rsquo;t feel quite correct. Perhaps, though, I\u0026rsquo;m being overcritical.\n","id":"/notes/added-search-powered-by-duckduckgo/","summary":"I\u0026rsquo;ve added a search bar to my site\u0026rsquo;s main navigation that\u0026rsquo;s powered by DuckDuckGo. Its styling doesn\u0026rsquo;t look quite right to me when on a desktop, though, and while it looks more at-home on mobile it also doesn\u0026rsquo;t feel quite correct. Perhaps, though, I\u0026rsquo;m being overcritical.","tag":"devlog webdesign duckduckgo ","title":"Added Search Powered by DuckDuckGo","type":"notes"},{"content":"","id":"/photos/finished-send-webmentions-form/","summary":"Add the Webmention Sending Form to all Single Page Content Templates. While in theory it will send the webmention to Webmention.io, I don\u0026rsquo;t know what happens afterwards. The best test would probably be to just try it and see. Until then I\u0026rsquo;ll keep it branched before I merge the changes into my site.","tag":"devlog webdesign hugo webmentions ","title":"Finished 'Send Webmentions' Form","type":"photos"},{"content":"Oh. My. God.\n","id":"/likes/oh-my-god-netflix/","summary":"Oh. My. God.","tag":"omg ","title":"Oh My God, Netflix!","type":"likes"},{"content":"I\u0026rsquo;ve sorted out how to have Hugo resize images larger than 1,080 pixels in width/height, and also started using HTML Tidy to clean up my generated pages. They weren\u0026rsquo;t itches I knew I had earlier this month, but they\u0026rsquo;re scratched now.\n","id":"/notes/image-resize-and-tidy/","summary":"I\u0026rsquo;ve sorted out how to have Hugo resize images larger than 1,080 pixels in width/height, and also started using HTML Tidy to clean up my generated pages. They weren\u0026rsquo;t itches I knew I had earlier this month, but they\u0026rsquo;re scratched now.","tag":"devlog hugo webdesign ","title":"Image Resize and Tidy","type":"notes"},{"content":"Man\u0026hellip; But I\u0026rsquo;d take anything else for furries other than the flu though. *biggest, most gigantic UWU*\n","id":"/replies/man-but-id-take-anything-else-for-furries-other-than-flu/","summary":"Man\u0026hellip; But I\u0026rsquo;d take anything else for furries other than the flu though. *biggest, most gigantic UWU*","tag":"sick furry mff ","title":"Man But I'd Take Anything Else for Furries Other Than Flu","type":"replies"},{"content":"So, reviewing my symptoms I got two days ago I\u0026rsquo;m 95% sure I got the flu. While I really want to go to see friends I don\u0026rsquo;t see often, I can\u0026rsquo;t in good conscience go to #MFF when I could become a Patient Zero. And all this makes me a sad (red) panda.\n","id":"/notes/got-the-flu-before-mff-2019/","summary":"So, reviewing my symptoms I got two days ago I\u0026rsquo;m 95% sure I got the flu. While I really want to go to see friends I don\u0026rsquo;t see often, I can\u0026rsquo;t in good conscience go to #MFF when I could become a Patient Zero. And all this makes me a sad (red) panda.","tag":"sick furry mff ","title":"Got the Flu Before MFF 2019","type":"notes"},{"content":"","id":"/photos/kawaii-desu-ne/","summary":"かわいいですね？！！🌟💞🍩☕","tag":"","title":"かわいいですね？！！🌟💞🍩☕","type":"photos"},{"content":"OMG I laughed pretty hard.\n","id":"/likes/trickaduu-irish-whiskey/","summary":"OMG I laughed pretty hard.","tag":"","title":"Mark Hayes - Irish Whiskey","type":"likes"},{"content":"","id":"/likes/petr-stastny-beware-of-shell-globs/","summary":"","tag":"terminal unix shell security ","title":"Beware of shell globs","type":"likes"},{"content":"It’s only been about a month since I’ve had my new domain up and a website created using Hugo, but already I feel like I got a lot done with it. It\u0026rsquo;s more or less exactly what I want according to the stuff I wrote during the start of my IndieWeb journey, and I think I got a pretty good amount of stuff working on it considering it\u0026rsquo;s only been a month.\nPost Things; Not Pages Thanks to Hugo\u0026rsquo;s Archetypes, I\u0026rsquo;m able to treat my content not as pages of a website but as actual things: Articles, Notes, Check-Ins, Bookmarks, Likes, Photos, and Replies. In the future, should I want to or need to, I can create new things to post.\nIt\u0026rsquo;s important to note, in my head, that I\u0026rsquo;m thinking of content as \u0026ldquo;Things\u0026rdquo; and not \u0026ldquo;Pages\u0026rdquo; or \u0026ldquo;Posts.\u0026rdquo; This allows me to try to think about how to structure the data of the things I\u0026rsquo;m posting and making it more descriptive not only to people (potentially) but to computers. For example, if I decide to scratch the itch I have right now to replace MyFlightradar24 with something else that\u0026rsquo;s created by me, I will probably think of the stuff I have not as \u0026ldquo;a list of coordinates\u0026rdquo; or \u0026ldquo;a list of pages with coordinates in it\u0026rdquo; but as \u0026ldquo;a flight.\u0026rdquo;\nStructure the data in the right way and my Hugo site (after creating templates)\u0026ndash;or any site that can consume my data correctly\u0026ndash;can display a map of all the flights I\u0026rsquo;ve taken in my lifetime (or specific criteria). As an aside, that could be pretty trivial to do since the majority of the hard stuff I\u0026rsquo;d need to do to show my flights are already taken care of when I made Check-Ins.\nDescribe Your Data I\u0026rsquo;ve deviated from IndieWeb convention when it came to documenting my content. Microformats Wiki\u0026rsquo;s h-entry and other kinds of microformats dominate the thoughts of a majority of IndieWeb sites. However, to me, it only describes a single thing. It actually can describe many things and many things well, but I wanted to describe a bit of my data more than what\u0026rsquo;s provided by it.\nDespite it being described as an openwashing anti-pattern, I\u0026rsquo;ve opted to describe my content in schema.org using the microdata attributes itemprop, itemscope, itemtype, and itemid. This is in addition to using h-entry. While describing already-described h-entry with schema.org is a bit redundant, this allowed me some practice on using schema.org with my content in anticipation to describing Flights and other Things in the future.\nTo add some considerations for users of silos like Facebook, Mastodon, and Twitter, I\u0026rsquo;ve also described my content using Open Graph and Twitter Cards. The rationale for this is to allow a prettier presentation of URLs from my site whenever shared on another silo.\nAren\u0026rsquo;t You Repeating Yourself? With the exception of Open Graph and Twitter Cards (they required \u0026lt;meta\u0026gt; tags in \u0026lt;head\u0026gt; versus marking up already visible content), I don\u0026rsquo;t think I\u0026rsquo;m repeating myself all that often. To be more specific, I am personally describing my data and creating my content once (in a Hugo content file). During site generation, Hugo (as a controller) takes that content and description (my data model) and formats it to the proper views for users (a web page) and for machines (Open Graph, Twitter Cards, Schema.org) using a template (a view model).\nWhile under the hood describing the process isn\u0026rsquo;t exactly Model-View-ViewModel, it thinks like that to me. The actual outputs may not be the leanest, but currently it still ends up lean and allows my content to be consumed in other ways in the future.\nWebmentions Since I\u0026rsquo;ve started I\u0026rsquo;ve always supported receiving Webmentions via Webmention.io, but I\u0026rsquo;ve never displayed any on my site yet. I\u0026rsquo;ve finally gotten around to utilizing the API to grab and display mentions on my content.\nI\u0026rsquo;ve also utilized Brid.gy to allow my content to syndicate to Twitter and Mastodon. There\u0026rsquo;s something magical about how it all works\u0026ndash;especially when I started seeing Twitter likes on my posts show up as comments on my site\u0026ndash;and really makes me feel like the IndieWeb method of doing things is a much better way of communicating with others on the Internet using content.\nItches Still Need Scratching Despite all the work I\u0026rsquo;ve done on my site thus far there\u0026rsquo;s still quite a few I want to scratch:\nCreate A New Thing: Flights MyFlightradar24 is currently what I\u0026rsquo;m using to log all my flights for work and for play. This isn\u0026rsquo;t a requirement of my job, but it\u0026rsquo;s more of a way to keep track of this relevant data and do useful things to it. There\u0026rsquo;s a bit inertia to changing out, but I\u0026rsquo;d like to hold on to this data instead of trusting that it\u0026rsquo;ll remain forever on another silo.\nI\u0026rsquo;ve started a new branch that I\u0026rsquo;m working on to eventually allow me to get all my data out of MyFlightradar24 and process it through Hugo to display the same data on my site. The hardest part is already finished; the annoying part is just writing out the templates and getting my data out of MyFlightradar24. Worse case I\u0026rsquo;ll need to manually write my flights into content files. But at least after I\u0026rsquo;m done with that I\u0026rsquo;ll own all my flight data information.\nAutomate Some Things Hugo is fast. It\u0026rsquo;s very fast. But the way I\u0026rsquo;m doing things is currently not. These are the things that I still manually do for my site:\n Have Hugo re-generate my pages when presented with new data Grab new Webmentions Get fallback map images for my check-ins Push my updated pages to my static site hosting service POSSE my content to Twitter and Mastodon using Brid.gy Send Webmentions to other sites  When I\u0026rsquo;m on my computer, these aren\u0026rsquo;t problematic, but because of the steps it certainly influences my behavior (i.e. Do I really want to Like or Reply to this thing right now?). On my phone the process is the same, except all done in Termux, and ergo the time considerations make it unacceptable to interact with content in a Right-Now fashion.\nUnfortunately, because of what I\u0026rsquo;m using right now (mainly that my host only serves static sites), I don\u0026rsquo;t even know where to start about scratching the automation itch. But eventually I\u0026rsquo;d like my sharing content with people and interacting with people\u0026rsquo;s content to be as easy as using a silo\u0026rsquo;s app. That\u0026rsquo;s not where I\u0026rsquo;m at right now, though.\nA Search Bar Personally? I can\u0026rsquo;t remember ever using a site\u0026rsquo;s search bar ever. Most of the time I end up going to my search engine of choice and searching for something. However, it does state that people appreciate having a search bar on a site, so I guess I better add that.\nA Bar to Send Webmentions This is a better thing that I should start putting on my posts, just above the comments. It allows someone to just put a URL of something that mentions me and sends my Webmention endpoint a Webmention. Other IndieWeb sites have done it and I think it\u0026rsquo;s a good thing to have\u0026ndash;especially since I\u0026rsquo;m not providing any kind of native or third party commenting (well, except for people who comment on my POSSE\u0026rsquo;d content on Twitter/Mastodon)\nHere\u0026rsquo;s to December! I\u0026rsquo;m hoping that I end up creating more content than working on the website in December because I should actually start just using what I\u0026rsquo;m making. But no doubt I want to get at least one or two of these itches scratched. So, for now, a pat on the back for me with a warm and fuzzy paw; I think I accomplished quite a bit in a month!\n","id":"/articles/state-of-my-website-december-2019/","summary":"It\u0026rsquo;s only been about a month since I\u0026rsquo;ve had my new domain up and a website created using Hugo, but I already feel like I got a lot done with it.","tag":"devlog indieweb webdesign hugo schema opengraph twitter webmentions ","title":"State of My Website December 2019","type":"articles"},{"content":"If, by this point, all those bags get to me, I\u0026rsquo;mma gonna go, \u0026ldquo;Good morning, lemme check that for you!\u0026rdquo; With an award-winning customer-service Barbie smile and a focused look under the glasses full of \u0026ldquo;I Insist\u0026rdquo; energy.\n","id":"/replies/good-morning-lemme-check-that-for-you/","summary":"If, by this point, all those bags get to me, I\u0026rsquo;mma gonna go, \u0026ldquo;Good morning, lemme check that for you!\u0026rdquo; With an award-winning customer-service Barbie smile and a focused look under the glasses full of \u0026ldquo;I Insist\u0026rdquo; energy.","tag":"","title":"Good Morning Lemme Check That for You","type":"replies"},{"content":"","id":"/likes/brad-sheppy-this-is-a-mood/","summary":"","tag":"","title":"Brady Agrees It's A Mood","type":"likes"},{"content":"","id":"/likes/toby-every-mff-travel-season/","summary":"","tag":"","title":"Toby SnowWolf's MFF Tweet","type":"likes"},{"content":"A bit of a rest week this week. The only trip I have is an easy three day turn to/from Las Vegas. This gives me plenty of time to just enjoy a few days off, plan out my holiday purchases, and find a room to crash for Midwest FurFest #MFF2019\n","id":"/notes/a-bit-of-a-rest-week/","summary":"A bit of a rest week this week. The only trip I have is an easy three day turn to/from Las Vegas. This gives me plenty of time to just enjoy a few days off, plan out my holiday purchases, and find a room to crash for Midwest FurFest #MFF2019","tag":"furry mff ","title":"A Bit of a Rest Week","type":"notes"},{"content":"Hurrah, webmentions are now displayed! My implementation of it for my site is done during Hugo\u0026rsquo;s static generation, so alack new mentions are not displayed in real time. Yet. Maybe soon?\n","id":"/notes/hurrah-webmentions-are-now-displayed/","summary":"Hurrah, webmentions are now displayed! My implementation of it for my site is done during Hugo\u0026rsquo;s static generation, so alack new mentions are not displayed in real time. Yet. Maybe soon?","tag":"devlog webmentions indieweb hugo ","title":"Hurrah, Webmentions Are Now Displayed!","type":"notes"},{"content":"So much metadata, but now all the posting types have additional metadata in the form of OpenGraph (Facebook), Twitter Cards (Twitter), and Schema.org (Google). But man, that was a total slog to actually make sure it all works.\n","id":"/notes/so-much-metadata/","summary":"So much metadata, but now all the posting types have additional metadata in the form of OpenGraph (Facebook), Twitter Cards (Twitter), and Schema.org (Google). But man, that was a total slog to actually make sure it all works.","tag":"devlog webdesign schema opengraph twittercards ","title":"So Much Metadata","type":"notes"},{"content":"","id":"/photos/coopers-hawk-jambalaya/","summary":"Having the rice atop the jambalaya was a bit of a surprise to me. It was seasoned, we thought, by cooking the rice with some form of citrus. It provided some spice, though I would\u0026rsquo;ve liked a little less saltiness to it.","tag":"food entree cajun ","title":"Cooper's Hawk Jambalaya","type":"photos"},{"content":"","id":"/photos/coopers-hawk-shaved-sprouts/","summary":"This was a pleasant and light salad with a bit of crunch thanks to the freshly shaved brussels sprouts. I think I would\u0026rsquo;ve liked the almonds candied, though.","tag":"food salad vegetables ","title":"Shaved Sprouts Salad from Cooper's Hawk","type":"photos"},{"content":"","id":"/photos/coopers-hawk-calamari/","summary":"The breading was nicely light on the calamari, though the method it was fried seemed like it clumped a bit. It was also a little cooler than I liked, but nonetheless delicious.","tag":"food seafood appetizers ","title":"Cooper's Hawk Calamari","type":"photos"},{"content":"Sister and sister’s boyfriend offered to take me here for the first time. It was actually pretty delicious, though the ambiance was a bit more active and noisier than I would\u0026rsquo;ve preferred. Good energy, though, and delicious (albeit on the salty side) food and wine.\n","id":"/check-ins/coopers-hawk-winery/","summary":"Sister and sister\u0026rsquo;s boyfriend offered to take me here for the first time.","tag":"food wine restaurants dinner ","title":"Cooper's Hawk Winery \u0026 Restaurants","type":"check-ins"},{"content":"That\u0026rsquo;s me after working a flight after ten hours. Usual symptoms for me is I start putting and pouring ice and sodas into a napkin instead of a glass. Hopefully no damage was done to the ports, though!\n","id":"/replies/thats-me-after-working-a-flight-after-ten-hours/","summary":"That\u0026rsquo;s me after working a flight after ten hours. Usual symptoms for me is I start putting and pouring ice and sodas into a napkin instead of a glass. Hopefully no damage was done to the ports, though!","tag":"funny technology tired ","title":"That's Me After Working a Flight After Ten Hours","type":"replies"},{"content":"","id":"/likes/why-yes-i-did-just-plug-a-usb-c-hard-drive-into-a-usb-a-port/","summary":"","tag":"funny technology tired ","title":"Why Yes I Did Just Plug a USB-C Hard Drive Into a USB-A Port","type":"likes"},{"content":"Just added \u0026lsquo;View on Silo\u0026rsquo; links. Currently it reads a syndication link of a post. If it recognizes the host it will show a link with \u0026lsquo;View on\u0026hellip;\u0026rsquo; as a title attribute and text. It\u0026rsquo;d be nicer if it was more actionable than that, but that\u0026rsquo;s a next step. Also, there\u0026rsquo;s a mysterious margin on the Timeline for the buttons and I can\u0026rsquo;t sort out which property is affecting it.\n","id":"/notes/just-added-view-on-silo-links/","summary":"Just added \u0026lsquo;View on Silo\u0026rsquo; links. Currently it reads a syndication link of a post. If it recognizes the host it will show a link with \u0026lsquo;View on\u0026hellip;\u0026rsquo; as a title attribute and text. It\u0026rsquo;d be nicer if it was more actionable than that, but that\u0026rsquo;s a next step. Also, there\u0026rsquo;s a mysterious margin on the Timeline for the buttons and I can\u0026rsquo;t sort out which property is affecting it.","tag":"devlog webdesign css indieweb ","title":"Just Added 'View on Silo' Links","type":"notes"},{"content":"I added taxonomies to my site! To do it I did a bit of creative fooling around (oh murr) with Hugo and the HTML details tag to show/hide my site\u0026rsquo;s sections (called Types on my site) and tags. Next up: show a \u0026lsquo;View on Twitter/Mastodon\u0026rsquo; button.\n","id":"/notes/i-added-taxonomies-to-my-site/","summary":"I added taxonomies to my site! To do it I did a bit of creative fooling around (oh murr) with Hugo and the HTML details tag to show/hide my site\u0026rsquo;s sections (called Types on my site) and tags. Next up: show a \u0026lsquo;View on Twitter/Mastodon\u0026rsquo; button.","tag":"devlog webdesign hugo ","title":"I Added Taxonomies to my Site","type":"notes"},{"content":"","id":"/likes/dingotech-oh-wow/","summary":"","tag":"travel ","title":"Oh Wow","type":"likes"},{"content":"Around a month ago I finally bought my domain name and thought about how I wanted to utilize my new stake on the Internet. The IndieWeb philosophies of my content is mine, interconnectedness, and control of my content appealed to me quite a bit. After thinking about the goals I wanted for my online presence, I went to the IndieWeb site and sorted through the process of getting myself on the Indie Web.\nMy Website is my User Name When I was formulating the goals for my site, I thought about people\u0026rsquo;s current usage patterns when interacting with other people on the Internet:\n Snapchat has the concept of Snapcodes. People on the platform can point their smartphone cameras on another person\u0026rsquo;s Snapcode to start following them to see stories or send messages. Twitter and Mastodon utilize user names. People can follow others and send messages to each other just by knowing their names on the platform. People communicate to each other on e-mail by sending e-mail addresses.  In short, when people want to communicate in any fashion, they need an identifier. Thing is, I wanted a domain name, but I didn\u0026rsquo;t really want a more traditional top-level domain. Opting out of traditionally-chosen top-level domains like .com or .me, I decided on a domain hack of the user name I use most often in other places on the Internet.\nChoosing this unconventional domain name gives people familiar with my user name on the Internet an easy way to remember my website (oh, it\u0026rsquo;s just sentamalin with a \u0026lsquo;.\u0026rsquo; between the \u0026lsquo;l\u0026rsquo; and the \u0026lsquo;i\u0026rsquo;). It also allows me to name things like e-mail or Stellar federated addresses in a more action-oriented fashion:\n tip*sentamal.in (For tipping me in Stellar Lumens) pay*sentamal.in (For paying an invoice in Stellar Lumens) email@sentamal.in (For sending regular e-mails) hire.sentamal.in (Not implemented, but could be a redirect to my portfolio)  Plus, it\u0026rsquo;s just kinda cool to have it; it\u0026rsquo;s something different compared to the number of name-dot-com domains around. I probably lose a bit of professional points, but I think the value I get from having it be interesting makes up for it.\nIn short, my domain name should be treated as if it\u0026rsquo;s my business card.\nHTML is my Lowest Common Denominator Of all the ways to share information, HTML is probably the most accessible way for anyone to get anything I post. You can still follow me on your social network of choice, for example, since I\u0026rsquo;m working on making sure my content syndicates to other places, but nobody should be forced to make an account somewhere or download an app to read and interact with the things I create.\nAs such, I wanted to make sure that I had good HTML for my pages from the get-go. To the best of my knowledge, all of my HTML validates correctly and I intend to keep validations correct as I continue fleshing out my site more and more. I also intend to utilize Microformats extensively so my usage of other publishing formats and services can be at a minimum.\nI also test and make sure my content is readable on text-based browsers like lynx. While this alone doesn\u0026rsquo;t testify that my website is completely accessible, it\u0026rsquo;s a good place to start, and I can work on further accessibility as I continue my IndieWeb journey.\nMy Website is my Business Card Properly using Microformats and HTML is all I need to make sure that my domain name will suffice as my business card. Anybody going to my home page will see the equivalent of a user profile and all the details people expect from a profile:\n Name Profile Picture Description/Bio Other Information OpenPGP Key Contact Links  Formatted in the h-card microformat, this can allow an Address Book application that supports h-card to easily add me as a contact. However, a separate app is not required; people are free to simply bookmark the page, if they want to.\nBecause the links to my other social network profiles have the rel=\u0026quot;me\u0026quot; attribute, this also allows me to log-in to websites that utilize IndieAuth with just my domain name. Alternatively, because I provide an OpenPGP Key, services (including IndieAuth) can also use my key to authenticate me to their servers and services.\nMy Website is my Timeline In addition to being my business card, visiting my website shows my timeline, a feed of interactions (marked up with the h-feed microformat) I\u0026rsquo;ve been doing on the Internet. Like my business card, a Reader application may easily consume my posts with just my domain name alone, but people are free to just bookmark my site.\nI\u0026rsquo;m presenting my web activity in chronological order so that people can know what I\u0026rsquo;ve been doing with my time on the Internet.\nMy Posts are Multiple Things Inside my h-feed are a bunch of things I posted of various content types. All of them are formatted in h-entry and represent a variety of post types common in blogs and other social networks:\n Articles (Long-form content I\u0026rsquo;ve written) Bookmarks (Links I\u0026rsquo;ve saved from elsewhere) Check-Ins (Places I\u0026rsquo;ve visited) Likes (Things I\u0026rsquo;ve generally enjoyed) Notes (Short-form content I\u0026rsquo;ve written) Photos (A single picture; sharing an album is next) Replies (A reply to content shared elsewhere)  Again, relevant applications can read this and present it to someone, but it\u0026rsquo;s all available on the site anyways. Future content types are easily made thanks to Hugo, an open-source static site generator that I\u0026rsquo;m using to manage my site. Admittedly I didn\u0026rsquo;t start out with any kind of CMS and was editing my sites by hand. I ended up spending more time writing HTML thatn writing content, so I decided to make the switch.\nMy Website can Send Replies Other social networks like Facebook, Twitter, and Mastodon allow their users to like, re-post, and reply to other people\u0026rsquo;s content. Thanks to Webmentions, I\u0026rsquo;m able to do the same just by creating a new post. As my site is a static site generated by Hugo, I\u0026rsquo;m utilizing Telegraph to send other sites a Webmention whenever I post something that mentions them.\nUnfortunately this is currently not automatic yet. I need to do some thinking about how to make it automatic, but I don\u0026rsquo;t anticipate it to be hard. For now Telegraph works fine, and worse case I can rely on curl to send a Webmention as well.\nMy Website can Receive Replies Thanks to Webmention.io my site can receive any Webmentions sent to my from someone else! That being said\u0026hellip; I haven\u0026rsquo;t implemented anything yet for people to see the Webmentions sent to me. But someday soon, it will.\nMy Website Syndicates Specifically, my website syndicates to Twitter and Mastodon. None of this is automatic yet, and I\u0026rsquo;m having a few quirks to sort out, but I\u0026rsquo;m able to syndicate to these two networks thanks to Brid.gy.\nIn addition, when someone on those social networks interacts with my content, Brid.gy sends a Webmention back to my site. This means that my content\u0026rsquo;s replies, likes, re-posts, and other interactions can be seen by everyone instead of being limited to a single service.\nMy Website is on the P2P Web Anyone can visit my website just by going to my URL. In addition, for those who are using Beaker Browser, you can also view my website in a peer-to-peer manner through the DAT Protocol.\nNote that at this time, I think, viewing it through DAT breaks Webmentions. I\u0026rsquo;d need to do things (perhaps process the current Webmentions at the time when generating my site through Hugo?) to have Webmentions displayed, and I\u0026rsquo;m unsure how to send decentralized Webmentions at this time.\nBut I\u0026rsquo;m not Done Yet! Even though I\u0026rsquo;ve gotten a lot done, there\u0026rsquo;s still a lot to do. Some of it might be beyond my skills and scope, but part of the fun is learning how to do it and have it working right.\nSome of these outstanding things I want for my site are:\n Show any Webmentions received from others Give an easy way for people to interact with my content via their own site or their social network of choice Add OpenGraph and Twitter Cards data to display my content a little nicer on social networks that don\u0026rsquo;t show preview links nicely without it Paginate the main feed (I\u0026rsquo;ve already finished the work on this on a branch, however I haven\u0026rsquo;t merged it yet because I need to figure out if I want to paginate in the first place) Utilize taxonomies like Categories and Tags on my posts to facilitate easier searching and related-post discovery Add search capabilities  So\u0026hellip; Yeah! I\u0026rsquo;m having fun, and it\u0026rsquo;s nice to have my own space on the Internet. I hope I continue to enjoy this journey.\n","id":"/articles/start-of-my-indieweb-journey/","summary":"After thinking about the goals I wanted for my online presence, I went to the IndieWeb site and sorted through the process of getting myself on the Indie Web.","tag":"webdesign indieweb ","title":"Start of My IndieWeb Journey","type":"articles"},{"content":"","id":"/bookmarks/metadata-markup/","summary":"","tag":"webdesign ","title":"Metadata Markup","type":"bookmarks"},{"content":"","id":"/likes/signs-you-might-be-traveling-too-much/","summary":"","tag":"travel ","title":"Signs You Might Be Traveling Too Much","type":"likes"},{"content":"","id":"/likes/deep-dive-css-font-metrics-line-height-and-vertical-align/","summary":"","tag":"webdesign css ","title":"Deep Dive CSS: Font Metrics, line-height and vertical-align","type":"likes"},{"content":"Ketchup on hot dogs is a perfectly acceptable condiment anywhere in the world, even in Chicago.\n","id":"/replies/ketchup-on-hot-dogs/","summary":"Ketchup on hot dogs is a perfectly acceptable condiment anywhere in the world, even in Chicago.","tag":"food ","title":"Ketchup on Hot Dogs","type":"replies"},{"content":"Twitter/Mastodon syndication is a little odd. Mainly my check-ins are showing up as photos without h-geo information being forwarded, and photo summaries aren\u0026rsquo;t showing up as expected. Thinking is required.\n","id":"/notes/twitter-mastodon-syndication-a-little-odd/","summary":"Twitter/Mastodon syndication is a little odd. Mainly my check-ins are showing up as photos without h-geo information being forwarded, and photo summaries aren\u0026rsquo;t showing up as expected. Thinking is required.","tag":"twitter mastodon syndication microformats ","title":"Twitter/Mastodon Syndication a Little Odd","type":"notes"},{"content":"","id":"/photos/staying-positive/","summary":"A BrightVibes sign that says: \u0026ldquo;Staying positive doesn\u0026rsquo;t mean you have to be happy all the time. It means that even on hard days you know there are better ones ahead.\u0026rdquo;","tag":"positive ","title":"Staying Positive","type":"photos"},{"content":"","id":"/photos/chins-up/","summary":"Flight attendants, prepare chins for take up. #chinsupbaby","tag":"selfie ","title":"Chins Up","type":"photos"},{"content":"Been a while hanging with crew. I don’t do it often, but when I can it’s pretty darn great. This Chili’s, though, offered 2-4-1 drinks at the bar, so it was a good place to chill after work.\n","id":"/check-ins/been-a-while-hanging-with-crew/","summary":"Been a while hanging with crew. I don\u0026rsquo;t do it often, but when I can it\u0026rsquo;s pretty darn great. This Chili\u0026rsquo;s, though, offered 2-4-1 drinks at the bar, so it was a good place to chill after work.","tag":"food layovers ","title":"Been a While Hanging With Crew","type":"check-ins"},{"content":"Mary and Joseph. Angelfire still exists and offers free websites, except it\u0026rsquo;s everything from its past glory plus HTML5! Why would I need WP/Hugo/Angular/AMP when I could have Angelfire Site Builder?!\n","id":"/notes/angelfire-still-exists/","summary":"Mary and Joseph. Angelfire still exists and offers free websites, except it\u0026rsquo;s everything from its past glory plus HTML5! Why would I need WP/Hugo/Angular/AMP when I could have Angelfire Site Builder?!","tag":"webdesign ","title":"Mary and Joseph, Angelfire Still Exists","type":"notes"},{"content":"Finished check-ins. I\u0026rsquo;m utilizing Leaflet for an interactive map on single pages and a static image as a fallback, for feeds, and for microformat consumption. This brings my list of types of postable content to 6: Check-Ins, Likes, Notes (equivalent to Toots/Tweets, Re-Post-able), Photo (singular, more like Instagram, Re-Post-able), Posts (blog post/article, Re-Post-able), and Replies.\n","id":"/notes/finished-checkins/","summary":"Finished check-ins. I\u0026rsquo;m utilizing Leaflet for an interactive map on single pages and a static image as a fallback, for feeds, and for microformat consumption. This brings my list of types of postable content to 6: Check-Ins, Likes, Notes (equivalent to Toots/Tweets, Re-Post-able), Photo (singular, more like Instagram, Re-Post-able), Posts (blog post/article, Re-Post-able), and Replies.","tag":"webdesign indieweb geolocation ","title":"Finished Check-Ins","type":"notes"},{"content":"Third day of bad sleep. After working red-eyes consistently, it\u0026rsquo;s always hard to get back into a normal schedule of things. Been failing at just taking a morning nap and there\u0026rsquo;s an early show tomorrow. Eff.\n","id":"/notes/third-day-of-bad-sleep/","summary":"Third day of bad sleep. After working red-eyes consistently, it\u0026rsquo;s always hard to get back into a normal schedule of things. Been failing at just taking a morning nap and there\u0026rsquo;s an early show tomorrow. Eff.","tag":"emotions ","title":"Third Day of Bad Sleep","type":"notes"},{"content":"I went through some older DAT posts and imported them into my site. Originally I had posts as single DAT archives and only accessible through Beaker Browser. I\u0026rsquo;ve lost the one-DAT-per-post mentality, but now it\u0026rsquo;s accessible through whichever means you can reach my URL.\n","id":"/notes/imported-old-dat-posts/","summary":"I went through some older DAT posts and imported them into my site. Originally I had posts as single DAT archives and only accessible through Beaker Browser. I\u0026rsquo;ve lost the one-DAT-per-post mentality, but now it\u0026rsquo;s accessible through whichever means you can reach my URL.","tag":"dat webdesign ","title":"Imported Old DAT Posts","type":"notes"},{"content":"Finished setting up Hugo for my static site. Beforehand I was pretty determined on just doing everything by hand. Until, well, I spent more time updating HTML than creating content. I\u0026rsquo;m glad I did this sooner than later.\n","id":"/notes/finished-setting-up-hugo/","summary":"Finished setting up Hugo for my static site. Beforehand I was pretty determined on just doing everything by hand. Until, well, I spent more time updating HTML than creating content. I\u0026rsquo;m glad I did this sooner than later.","tag":"hugo webdesign ","title":"Finished Setting Up Hugo","type":"notes"},{"content":"Derp. So it turns out I was properly linking to other posts for Webmentions to work. Thing is I can\u0026rsquo;t use Telegraph to send mentions to myself. Using curl worked, and Webmention.io picked it up properly.\n","id":"/notes/derp/","summary":"Derp. So it turns out I was properly linking to other posts for Webmentions to work. Thing is I can\u0026rsquo;t use Telegraph to send mentions to myself. Using curl worked, and Webmention.io picked it up properly.","tag":"devlog webmentions webdesign indieweb ","title":"Derp","type":"notes"},{"content":"A pretty good guide to how to comment on his posts; I want my site to be this easy as well.\n","id":"/likes/how-to-comment/","summary":"A pretty good guide to how to comment on his posts; I want my site to be this easy as well.","tag":"indieweb webmentions ","title":"How to comment","type":"likes"},{"content":"I\u0026rsquo;ve added support for Webmentions via Webmention.io and Telegraph. Let\u0026rsquo;s see if all this works! Note that all I\u0026rsquo;ve done is added support for sending and receiving; I haven\u0026rsquo;t put any work in to actually displaying received Webmentions yet.\n","id":"/replies/ive-added-support-for-webmentions/","summary":"I\u0026rsquo;ve added support for Webmentions via Webmention.io and Telegraph. Let\u0026rsquo;s see if all this works! Note that all I\u0026rsquo;ve done is added support for sending and receiving; I haven\u0026rsquo;t put any work in to actually displaying received Webmentions yet.","tag":"webmentions ","title":"I've added support for Webmentions","type":"replies"},{"content":"Icon attribution footer is done! Now it\u0026rsquo;s just time to make a pretty theme, import my old posts, make a few new ones, and then figure out Webmention support for this static site.\n","id":"/notes/icon-attribution-footer-is-done/","summary":"Icon attribution footer is done! Now it\u0026rsquo;s just time to make a pretty theme, import my old posts, make a few new ones, and then figure out Webmention support for this static site.","tag":"webdesign devlog webmentions ","title":"Icon attribution footer is done!","type":"notes"},{"content":"Just finished the CSS; icon attribution next. I want to get either the harder parts or the most boring parts taken care of first before moving into fun things. I need to create an area in the footer to access the CC Attributions for the icons I\u0026rsquo;m using, then need to sort out WebMentions. But, honestly? I may just decide to work on theming (and replacing the text with icons on mobile for the menu).\n","id":"/notes/just-finished-the-css/","summary":"Just finished the CSS; icon attribution next. I want to get either the harder parts or the most boring parts taken care of first before moving into fun things. I need to create an area in the footer to access the CC Attributions for the icons I\u0026rsquo;m using, then need to sort out WebMentions. But, honestly? I may just decide to work on theming (and replacing the text with icons on mobile for the menu).","tag":"css webdesign devlog ","title":"Just finished the CSS","type":"notes"},{"content":"Because it\u0026rsquo;s almost, but not quite, the season. A cringey mash-up that I can\u0026rsquo;t help loving.\n","id":"/likes/mariah-carey-soulja-boy-mashup/","summary":"Because it\u0026rsquo;s almost, but not quite, the season. A cringey mash-up that I can\u0026rsquo;t help loving.","tag":"mashups music ","title":"Mariah Carey - Soulja Boy Mashup","type":"likes"},{"content":"Wah! That was a slog. But at least I got the sections that I think want set up for the site, and things would be relatively okay for posting and creating content on, now! Before I continue on, I\u0026rsquo;m gonna try to tweak the CSS for responsiveness (because there is no responsive design at all at the moment).\n","id":"/notes/wah-that-was-a-slog/","summary":"Wah! That was a slog. But at least I got the sections that I think want set up for the site, and things would be relatively okay for posting and creating content on, now! Before I continue on, I\u0026rsquo;m gonna try to tweak the CSS for responsiveness (because there is no responsive design at all at the moment).","tag":"devlog webdesign css ","title":"Wah! That was a slog.","type":"notes"},{"content":"I am in the process of re-creating my library. In addition to importing any DAT links I have (and making sure they only show up if in a DAT-compatible browser), I need to find a way of displaying all sorts of content in a harmonious fashion.\n","id":"/library/","summary":"I am in the process of re-creating my library. In addition to importing any DAT links I have (and making sure they only show up if in a DAT-compatible browser), I need to find a way of displaying all sorts of content in a harmonious fashion.","tag":"","title":"Library","type":"library"},{"content":"This has been on my list for a while, but I finally got myself a new domain. It\u0026rsquo;s actually a domain hack of my usual username while on the Internet, which works well because most, if not all, of my usernames on the Internet proved by Keybase are the same. A name alone, after all, doesn\u0026rsquo;t guarantee that you\u0026rsquo;re talking to the same person, but the cryptographic proofs Keybase provides does. It\u0026rsquo;s just nicer when all the names are essentially the same.\nAs it stands, there\u0026rsquo;s nothing much here. There\u0026rsquo;s this page. There\u0026rsquo;s a few things that let me accept Basic Attention Tokens as a tip or as auto-contribution. A federated Stellar address also exists (tip*sentamal.in) if you want to buy me a coffee or a beer that way! It\u0026rsquo;s amazing what can be done with static content alone.\nThat being said\u0026hellip; There\u0026rsquo;s really nothing here. But it\u0026rsquo;s a start! I\u0026rsquo;ll start designing later.\n","id":"/articles/a-new-domain/","summary":"This has been on my list for a while, but I finally got myself a new domain.","tag":"webdesign stellar bravebrowser ","title":"A New Domain!","type":"articles"},{"content":"The beginning of this month marked a few significant changes for me. The first one was celebrating a birthday (I’m 32 now!). The other one is discontinuing a relationship I’ve had with a best friend of more than ten years. The latter has been eating me up during my quiet moments during the day even though I’m trying to move on and move forward.\nTruth be told nothing much about my schedule has changed; I still have the same (over)load of variables to work with during the day despite it. However, I\u0026rsquo;ve found myself to be able to accomplish more things that I\u0026rsquo;ve needed to take care of to take care of me. The consequence is there\u0026rsquo;s a certain guilt involved in all of it because, for the most part, it\u0026rsquo;s generally hard to cease a relationship after that long of a time, and also, because it\u0026rsquo;s been a long time, you\u0026rsquo;d think there\u0026rsquo;d be a way to repair it. It\u0026rsquo;s strange feeling like you should have guilt for taking care of you and doing what you need or want to be doing with your time. But I think it\u0026rsquo;s only strange because I tend to be a person who doesn\u0026rsquo;t do those things normally.\nI get that hurt people hurt people. My best friend was certainly hurting\u0026ndash;for a very long while. But slowly, yet surely, I got to a point where I was living more for them than I was for me. Current activities would drop whenever they called. Potential plans would get overridden because I\u0026rsquo;d check on them and they wanted to do a certain thing. I\u0026rsquo;ve seen them more than my family, and my co-workers more than my family. Any other friends even less than my family. Strangers became more of an outlet for heartfelt conversations and catharsis than best friend or others because when all your time was spent on best friend you had to take whatever outlet you can take and be grateful for it. Pain does amazing things to people and tends to make people who care prioritize based on others' pain. But it doesn\u0026rsquo;t work. It didn\u0026rsquo;t work.\nWe had a conversation early in the month where they proceeded to tell me that I wasn\u0026rsquo;t being the kind of friend that a friend should be. What they said was, in essence, \u0026ldquo;I need you to be here; where are you?!\u0026rdquo; I explained my current situation and stresses and they were unconvinced and thought I could be there more. \u0026ldquo;Desperate times call for desperate measures; crises don\u0026rsquo;t happen on your timetable!\u0026rdquo; What I heard, in essence, was \u0026ldquo;after I\u0026rsquo;ve prioritized you over family and friends, after I\u0026rsquo;ve given every material need I can spare, after I told you what was going on with me, and even with the length of your relationship, you can\u0026rsquo;t trust that I\u0026rsquo;ve given you all I\u0026rsquo;ve had when I\u0026rsquo;m telling you that I have given everything? Are you really entitling yourself to more of my time and energy than I can afford even when I\u0026rsquo;ve already been giving you everything to the sacrifice of the things that I need to take care of for me?\u0026rdquo;\nWe cooled off, tabled the conversation. I talked with the same strangers that would come to at least help me sort out. I\u0026rsquo;ve asked trusted people that I considered friends. I\u0026rsquo;ve talked to professionals (thank goodness for union and company-provided EAPs). I returned to my best friend, via e-mail, a response I thought was well written and showed how and why I felt pained. They felt blindsided that I could feel offended over \u0026ldquo;one unsavory conversation.\u0026rdquo; We cooled off again and then they responded, asking if I\u0026rsquo;m depressed, and added nostalgia into the mix of good times in the past. It was disguised as a sentiment of care; it came out as a deflection and putting the blame on our \u0026lsquo;unsavory conversation\u0026rsquo; and my response on me and my depression. There was no addressing what I\u0026rsquo;ve written.\nI had to cut it off. I get it that hurt people hurt people, but personally I cannot bear the fact that someone can\u0026rsquo;t trust what I say to be true after this long of a relationship, I cannot bear the fact that my feelings about how I felt they were unaddressed, and I cannot bear the fact that me (or my depression) was put to blame for the current situation. I had to cut it off. I did cut it off.\nIt\u0026rsquo;s been twelve days since I\u0026rsquo;ve initiated no contact. I\u0026rsquo;ve gotten quite a few things done and I\u0026rsquo;m just trying to keep taking care of myself. I\u0026rsquo;m trying to reflect and own on things I may have done, yet still being gentle on myself. Yet this is still hard.\nAre things like this always hard? Maybe they are, and I just need to be more gentle. Still, it\u0026rsquo;s hard.\n","id":"/articles/breakups-with-relationships-of-longetivity/","summary":"The beginning of this month marked a few significant changes for me. The first one was celebrating a birthday (I\u0026rsquo;m 32 now!). The other one is discontinuing a relationship I\u0026rsquo;ve had with a best friend of more than ten years. The latter has been eating me up during my quiet moments during the day even though I\u0026rsquo;m trying to move on and move forward.","tag":"relationships ","title":"Breakups with Relationships of Longetivity","type":"articles"},{"content":"It\u0026rsquo;s pretty clear from my profession that I travel quite a bit. I used to be excited about getting to stay at rather fancy hotels during my work stays. Eventually, it got to be a bit tiring and all the hotels started to look the same. Thankfully, when I travel for personal reasons I have a choice, and I usually prefer cheaper and unique boutique hotels. The Rambler Motel in Chula Vista, California, was a cutely-themed boutique motel that\u0026rsquo;s equidistant from San Diego, United States, and Tijuana, Mexico.\nWhile we didn’t spend too much time inside our rooms and the facilities, The Rambler Motel is themed in a beautiful interstate highway style, provided a comfortable place for winding down and sleeping for the next day, and is conveniently located to explore the sights and sounds of San Diego and Tijuana.\nPhotos The best way to describe the Rambler\u0026rsquo;s aesthetic is IKEA meets US Interstate. It\u0026rsquo;s actually quite cute!  My boyfriend and I appreciated the little arcade that they had in the lobby. Although a token machine was available none of the machines needed tokens to play. Much fun with Dig-Dug was had. It would be cute to have more machines available, or perhaps to get arcade cabinets that have multiple games.  Their gift shop area had a few oddities like the pet rock. I particularly appreciated the softcover copies of Jack Kerouac\u0026rsquo;s On The Road.  Amenities In addition to the arcade area and gift shop in their lobby, The Rambler Motel also had a pool area, complete with a whimsical inflatable pink flamingo flotation ring. Its location is near Seven Mile Casino, which is open 24/7 for games and for dining. A coffee shop was under construction in their facilities, but unfortunately that wasn\u0026rsquo;t open quite yet. I\u0026rsquo;d imagine going back to this place as a small weekend staycation once that\u0026rsquo;s open: wake up late, get some coffee and read a book, play some arcade games, swim in the pool, then head to San Diego or Tijuana for some night life before heading back to bed.\nIn-room amenities included free Wi-Fi, a flat-screen TV, a combination shower and tub, and toiletries. Ice is provided, but no microwaves or refrigerators were available in the room. Personally, I was bummed that there was no microwave or refrigerator, but it was something I could live with\u0026ndash;especially since I didn\u0026rsquo;t pack food or drink for this particular adventure.\nSan Diego\u0026rsquo;s trolley system was about a ten minute walk away from the hotel, making it extremely easy to get around. Restaurants of various budgets, stores like Wal-Mart or Target, and other attractions like the Living Coast Discovery Center are easy to reach. The room provides you a list of fourteen places to see and eat\u0026ndash;seven each for San Diego and Tijuana!\nI\u0026rsquo;d Stay Again! I\u0026rsquo;d definitely stay again if I wanted a weekend stay in San Diego. The Rambler Motel\u0026rsquo;s location between downtown San Diego and Tijuana makes it an easy home base for any trouble you plan to make in any of those cities. Yet its amenities also let you enjoy an affordable staycation using their facilities and the shops surrounding the motel.\n","id":"/check-ins/the-rambler-motel/","summary":"While we didn\u0026rsquo;t spend too much time inside our rooms and the facilities, The Rambler Motel is themed in a beautiful interstate highway style, provided a comfortable place for winding down and sleeping for the next day, and is conveniently located to explore the sights and sounds of San Diego and Tijuana.","tag":"reviews hotels ","title":"The Rambler Motel","type":"check-ins"},{"content":"I turned 32 yesterday, which personally isn’t much of a big affair (I usually like my birthdays to be far more casual and not a Big Deal). I think for me I’ve never desired the hullaballoo of grandiose celebrations. It’s not that I wouldn’t be appreciative of it; I guess it’s that I don’t need much. Since I was working throughout my entire birthday, I was able to enjoy the birthday messages I was sent through various mediums, but I also spent the time contemplating the relationships I have, I’ve had, and have been failing at.\nBirthday Wishes Highlights There were 18 people who sent a happy birthday message to me on Facebook yesterday. It may be a small amount, but it was a quality amount of people.  \u0026ldquo;Happy Birthday Don hope you have a great day I\u0026rsquo;m greatful to have you as a coworker your a aweomse FA who really taught me a lot when I was new on the line.\u0026rdquo; This meant a lot to me considering my upcoming promotion mid-this month.  My boyfriend sent me a message on Telegram, along with a spam of stickers as is amusingly usual from folks there.  An older couple who are friends with me for some longetivity sent me this card via e-mail. It\u0026rsquo;s sweet.  I need to tell the story of my other family in another post, but the TLDR of it all is it\u0026rsquo;s been incredibly difficult to keep in touch with them, and this is the consequence of what I get. I need to be in better touch.  A Relationship Lost TL;DR: Last week I had an unsavory conversation with my best friend. I personally thought that I was giving the relationship with them my all and that I\u0026rsquo;ve given all the time I could for them. They felt that I wasn\u0026rsquo;t giving enough and because of their need they needed more than I was giving. I understand that they felt hurt, but I reaffirmed that I couldn\u0026rsquo;t give more than I was giving. They were unconvinced. I told them that despite my care I don\u0026rsquo;t know how a relationship where they couldn\u0026rsquo;t trust I was giving my all and was requesting more could continue to work. They felt blindsided by the statement, apologized for hurting me, then sent a message a few days later that implied a blame-casting on me (or, rather, my depression) instead of the pain that I grieved. After talking with my EAP, priest, friends, and family, I made a difficult decision to stop the relationship.\nI\u0026rsquo;m on a regimen of No Contact at this time. It sucks and it hurts because I know that they\u0026rsquo;re hurting and hurt people hurt people. I would\u0026rsquo;ve loved to get a message from them as we normally do in the 10+ years we were together. It just can\u0026rsquo;t happen right now though. I\u0026rsquo;ll still pray and care, but for me and my needs the relationship can\u0026rsquo;t continue. Things hurt, but time will heal. I hope.\nThe Future I want to reassess my relationships and try to nurture ones that have fallen (like my relationship with my sister in the Philippines) and continue to enjoy the ones that are still there. I want to celebrate good things like this with the people who care, and to celebrate their successes as well in whatever way I can\u0026ndash;whether it\u0026rsquo;s in person or through messages.\nThanks for the birthday wishes, everyone, and I hope to hang with all y\u0026rsquo;all soon in however way we can.\n","id":"/articles/birthdays-and-relationships/","summary":"I turned 32 yesterday, which personally isn\u0026rsquo;t much of a big affair (I usually like my birthdays to be far more casual and not a Big Deal). I think for me I\u0026rsquo;ve never desired the hullaballoo of grandiose celebrations. It\u0026rsquo;s not that I wouldn\u0026rsquo;t be appreciative of it; I guess it\u0026rsquo;s that I don\u0026rsquo;t need much. Since I was working throughout my entire birthday, I was able to enjoy the birthday messages I was sent through various mediums, but I also spent the time contemplating the relationships I have, I\u0026rsquo;ve had, and have been failing at.","tag":"birthday relationships ","title":"Birthdays and Relationships","type":"articles"},{"content":"Imported from my old DAT check-in.\n","id":"/check-ins/ohare-international-airport/","summary":"Imported from my old DAT check-in","tag":"airports ","title":"O'Hare International Airport","type":"check-ins"},{"content":"I love that Flex Boxes exist. It makes it pretty fun to create new layouts and styles, and is definitely going to be part of my toolkit from now on. Of course, my first test with it is not the standard column layouts with resizable widths, but instead is a fixed-width tile style reminiscent of the Metro Design Language. Is it accessible? Well, the structure looks okay without styles. Is it pretty? I think so.\nActual Content as the UI I\u0026rsquo;ve admired Metro since it became commonplace throughout the Windows product. My first experience with it was with Windows 8, but the place where I finally fell in love with the design was my 3+ years of using a Windows Phone.\nBefore I started using my Samsung Galaxy Note 8, my smartphone usage was:\n Samsung Galaxy S7 Edge Microsoft Lumia 950 Microsoft Lumia 650 Nokia Lumia 1520 Nokia Lumia 920 Nokia N9  Part of my affection for Metro is due to my love of Swiss Style. While it never translated the best while using Windows on a PC, the fact that the content was the star and the driving force of the UI made it pleasurable on a phone. On the few times I ran into another Windows Phone user, our Start Screens always looked different. While mine may be personalized with tiles of calendars, important contacts, glanceable tiles showing social media and messages, and a scrolling-picture tile of a photo album I titled \u0026ldquo;Positive Memories,\u0026rdquo; another person\u0026rsquo;s phone may prioritize the games they played and the stream of Instagram pictures they\u0026rsquo;ve recently shared. No matter the person, the phone inevitably became the person\u0026rsquo;s device because their content defined the phone\u0026rsquo;s look and feel.\nRoadblocks There were some hard, to me, questions that I needed to answer while I made my new website. The driving force of Metro is to put content at the forefront. However, it\u0026rsquo;s graphical nature needed thought in the HTML and the CSS.\nMy main problem was in semantics. Will it make sense to read it without a stylesheet? Can someone using an assistive device still browse through my site and the various timeline entries represented as tiles? The content needs to be presented beautifully, of course, but all its beauty would be ruined if the information wasn\u0026rsquo;t accessible to people or machines.\nMy Process I started, first, simply structuring the content by using HTML5\u0026rsquo;s new semantic elements and Microformats. This is done to make sure that accessible devices could read the page, but can also parse the microformats to consume the data available in different ways. I followed this by a bunch of CSS trial and error.\nBefore starting this I had no idea of display: flex\u0026rsquo;s existence in CSS. I was dreading having a gigantic mass of \u0026amp;lt;div\u0026amp;gt;s to float. Or a huge mess of table cells. Flex boxes made the entire thing easy to style the way I want\u0026ndash;after a ton of trial and error. After I wrote all the CSS in one file, I separated the CSS into files defining structure for \u0026lsquo;big screen\u0026rsquo; and \u0026lsquo;small screen\u0026rsquo; devices, then separated out information that involved colors and backgrounds. Those styles were then copied and modified to create alternate stylesheets for high contrast (black on white) and inverse high contrast (white on black).\nThe Result? After all that, I created sample tiles in the timeline and tried it out. There\u0026rsquo;s a maximum width of 8 small tiles. As viewport width shrinks the tiles simply wrap to the next line, but maintain the grid. There\u0026rsquo;s a minimum width of 4 small tiles for the site\u0026rsquo;s look and feel.\nI\u0026rsquo;ve gotten my boyfriend\u0026rsquo;s help in trying it out on his iOS devices, but it worked for me on Linux and Android on various browsers. It looks nice and is pretty true to Metro. To my knowledge, it\u0026rsquo;s also accessible by virtue that without styles it\u0026rsquo;s readable and semantic. It\u0026rsquo;s accessibility is an assumption though; I\u0026rsquo;m hoping that it is. Sure, Beaker Browser is a desktop browser at this time, but I want to be ready for the future now.\nAll in all, I\u0026rsquo;m pretty proud of all of this\u0026ndash;especially since I haven\u0026rsquo;t designed anything or played with CSS since I closed down my eBook Publishing house almost two years ago. Doing this reminded me of the fun I used to have learning, experimenting, and creating. I hope I can continue this momentum and make more things in the future.\nUID URL sameAs Me I made a few decisions, too, in structuring the personal site, on the virtue of \u0026ldquo;UID URL sameAs Me.\u0026rdquo; I\u0026rsquo;m envisioning a future where a person, like a user name, can give a URL as their unique identifier. With that in mind, the posts in my timeline link to individual entries (as separate Dat archives like solo). My entries know to use my photo\u0026ndash;as defined in my UID URL\u0026ndash;as the image to show as an author, and also utilizes my current background as its background as a touch of presentational unity between discrete and decentralized Dat archives.\nI don\u0026rsquo;t know if it can happen, or if people choose it, or if I can contribute to such a future. But at least I can start preparing for it! If I get better at my coding skills (that I find lackluster) maybe I can start it or help it.\n","id":"/articles/bless-the-gods-for-css-flex-boxes/","summary":"I love that Flex Boxes exist. It makes it pretty fun to create new layouts and styles, and is definitely going to be part of my toolkit from now on. Of course, my first test with it is not the standard column layouts with resizable widths, but instead is a fixed-width tile style reminiscent of the Metro Design Language. Is it accessible? Well, the structure looks okay without styles. Is it pretty? I think so.","tag":"css webdesign ","title":"Bless the Gods for CSS Flex Boxes!","type":"articles"},{"content":"","id":"/photos/i-got-art/","summary":"My friend Kal\u0026rsquo;hona surprised pilot furs Turbulence, Jay, Horus, and me with this commission drawn by @ocdraco. Thanks for the late Christmas gift!","tag":"furry art ","title":"I Got Art!","type":"photos"},{"content":"This is mentioning something without saying what kind of mention it is. Hello there, my post!\n","id":"/notes/a-test-mention-with-nothing/","summary":"This is mentioning something without saying what kind of mention it is. Hello there, my post!","tag":"","title":"A Test Mention With Nothing","type":"notes"},{"content":"I was sitting down with my devices this evening to check how my OpenPGP keys were set up to make sure all of them are functioning okay and will do what I need whenever I would need them. Save for the fact that I took a plunge a month back and began a transition to using ECC (its compatibility isn’t like RSA’s across OpenPGP implementations, plus I’m using Curve25519 for encryption, which GnuPG provides but isn’t in OpenPGP’s RFC) everything looked fine, until I thought about what would happen if I lose my device?\nJust Revoke The Subkeys? The roleplay in my head, because I travel quite a bit and go through various security checkpoints, is \u0026ldquo;What do I do if I must surrender one of my devices on-hand?\u0026rdquo; The Guardian Project\u0026rsquo;s Ripple app, in Beta, would let me wipe OpenKeychain while I\u0026rsquo;m waiting in line for my turn, but that support isn\u0026rsquo;t implemented yet. In addition, while deleting something off my phone would be easy and inconspicuous enough to do while waiting in line, rummaging through my bags for my tablet or other technology would certainly mark me as Interesting\u0026ndash;possibly Interesting enough to be expedited through the process.\nIn any case, pondering this situation made me wonder if it\u0026rsquo;s possible to generate revocation certificates for my OpenPGP keys that revoke only the subkeys of a compromised device. Unfortunately, the answer is no; generated revocation certificates will revoke the entire key. Revoking the entire key seems too much like throwing the baby out with the bathwater in my situation, especially since I do not carry the secret material of my primary key on me.\nIn addition, since I don\u0026rsquo;t carry the secret material of my primary key on me, I would have no method of revoking the subkeys after I\u0026rsquo;ve surrendered any of my devices. I could just wait until I get to a trusted system to revoke the subkeys properly, but from the moment I surrender a device to the moment I get to a trusted computer, someone may have utilized my key material. I\u0026rsquo;m not particularly fond of that prospect.\nI began thinking of solutions for this theoretical problem.\nChanges to Public Keys are Merged It occurred to me that the public key material exported from gpg --export contains the public information about your key, along with signatures that certify certain things like your current and revoked user IDs and subkeys. The important thing I remembered is that when someone updates a public key, any additions\u0026ndash;like self-signatures stating that a subkey is revoked\u0026ndash;are merged with the current information in the key ring.\nBased on that knowledge, I booted up my trusted system and, for each of my devices:\n Exported my current public and secret keys to a respective file. Used gpg --edit-key to revoke the subkeys that would be on the device. Exported the public key material with the revocations to a new file. Deleted my public and secret keys from the key ring. Imported my public and secret files I created in step one.  What I\u0026rsquo;ve basically made are \u0026lsquo;per-device revocation certificates\u0026rsquo; masquerading as a public key file. Publishing the files I\u0026rsquo;ve made to a key server will merge the self-signatures that revoked the subkeys into my public key stored on the key server. People who already have my key will be able to note the revocation after they do an update (e.g. gpg --refresh-keys) on their key ring. The best benefit? I won\u0026rsquo;t need to revoke my entire key using an actual revocation certificate, and I won\u0026rsquo;t need to carry my secret key material to revoke any compromised subkeys.\nIt Works~~, But It\u0026rsquo;s Not Pretty~~ The biggest problem I foresee utilizing this process is those subkeys are marked revoked on the date I self-signed the revocation\u0026ndash;not on the day that I, say, published the change on a key server.\nFor example, let\u0026rsquo;s say I created the revocations today using the process I outlined, used my keys for a month, and then had to surrender a device. I have no way to properly revoke the subkeys because I don\u0026rsquo;t have my secret key material available for revocations. I publish the file I made for the particular device that was compromised to a key server, marking the subkeys as revoked on the date of the self signature. Even though I put PREEMPTIVE STOPGAP: A device has been compromised. as a description during the subkey revocation process, thus letting people know that this revocation was done pre-emptively, gnupg will still complain that a signature, ciphertext, or authentication was done during a time when a subkey should\u0026rsquo;ve been invalid because it was revoked\u0026ndash;even if said operations were done before I published the file to a key server.\nI\u0026rsquo;d consider that consequence unacceptable, but more acceptable than revoking an entire key via revocation certificate just because of a few compromised subkeys (again, throwing baby out with the bathwater), or carrying the secret key material with me to accomplish correct revocations (if I can help it, I won\u0026rsquo;t carry the secret key material of my primary key). It gives me a way to notify people not to trust operations done by a compromised subkey when I can\u0026rsquo;t revoke in the correct manner.\nIf a better solution exists to this problem, I\u0026rsquo;d be very glad to know it. But thus far, I can\u0026rsquo;t think of a better solution.\nUpdate: Because I\u0026rsquo;ve transitioned to a new key based on ECC, I revoked my old primary key using a Revocation Certificate I made for the purpose (key has been superseded). A prepared certificate was used because I knew, during the time, that I will not have access to my trusted computer.\nTurns out, using a revocation certificate issues a revocation based on the time I created the revocation certificate, and not the time that I used it. Ergo, the process I outlined above functions the exact same way as a revocation certificate, which is what I want to happen.\nAs an Aside This just further confirms my opinion that OpenPGP can get far too hard.\n","id":"/articles/a-creative-approach-to-revoking-openpgp-subkeys/","summary":"I was sitting down with my devices this evening to check how my OpenPGP keys were set up to make sure all of them are functioning okay and will do what I need whenever I would need them. Save for the fact that I took a plunge a month back and began a transition to using ECC (its compatibility isn\u0026rsquo;t like RSA\u0026rsquo;s across OpenPGP implementations, plus I\u0026rsquo;m using Curve25519 for encryption, which GnuPG provides but isn\u0026rsquo;t in OpenPGP\u0026rsquo;s RFC) everything looked fine, until I thought about what would happen if I lose my device?","tag":"openpgp privacy ","title":"A Creative Approach to Revoking OpenPGP Subkeys","type":"articles"}]