# testycool > Mostly LLMs, mostly. --- ## Pages - [Online Jupyter Notebook to HTML or PDF Converter](https://testy.cool/online-jupyter-notebook-to-html-or-pdf-converter/): This tool converts Jupyter Notebooks (. ipynb files) into formatted HTML or PDF documents entirely in your browser. You can... - [Tools](https://testy.cool/tools/): Various tools that I've coded in HTML/JS. Chrome Extension Icon Generator A quick way to generate icons for chrome extensions.... - [Chrome Extension Icon Generator](https://testy.cool/chrome-extension-icon-generator/): For when you're excited about the Chrome Extension you just vibe-coded, but you realize that you just got the most... - [Blog](https://testy.cool/blog/): Pellentesque tincidunt tristique neque, eget venenatis enim gravida quis. Fusce at egestas libero. Cras convallis egestas ullamcorper suspens. - [Contact](https://testy.cool/contact/): I'm always happy to connect. Whether it's feedback, questions, or suggestions. You can send me an email at right@testy. cool.... - [Privacy Policy](https://testy.cool/privacy-policy-2/): Effective Date: May 4th 2025 This Privacy Policy describes how TestyCool ("we," "us," or "our") collects, uses, and discloses your... - [About](https://testy.cool/about/): Pellentesque tincidunt tristique neque, eget venenatis enim gravida quis. Fusce at egestas libero. Cras convallis egestas ullamcorper suspens. --- --- ## Posts - [Fix Black/Gray Screen Issues with ShareX or Windows Screenshot Tools](https://testy.cool/notes/fix-black-gray-screen-issues-sharex-or-windows-screenshot-tools/): The Problem If you're experiencing these frustrating screen capture issues on Windows 10: ShareX showing only black screens when capturing... - [Web Scraping with Playwright Aria Snapshots in crawl4ai](https://testy.cool/tutorials/web-scraping-with-playwright-aria-snapshots-in-crawl4ai/): I recently came across Playwright's Aria Snapshots, when testing the Playwright MCP. As someone who regularly needs to extract data... - [The farther from the public or the money, the more bullshit I want to optimize](https://testy.cool/ramblings/the-farther-from-the-public-or-the-money-the-more-bullshit-i-want-to-optimize/): I'm noticing that because I work "in the back", and what I produce doesn't feel like it will immediately be... - [Trying Image Upscalers & Enhancers](https://testy.cool/ramblings/trying-image-upscalers-enhancers/): Most image upscalers/enhancers I've found aren't great for with fine details. Image upscalers/enhancers won't do all the work if you... - [Failed: Custom CSS in Glance Dashboard on Coolify](https://testy.cool/tutorials/failed-custom-css-in-glance-dashboard-on-coolify/): I wanted to use a custom CSS theme for my Glance dashboard. The default font is JetBrains Mono, which is... - [Ask yourself 'Does this move the needle' while doing something](https://testy.cool/ramblings/ask-yourself-does-this-move-the-needle-while-doing-something/): Instead of getting lost into exploring some idea that probably only improves your workflow, and takes 30mins, after you explored... - [Do an imperfect thing to improve what you want](https://testy.cool/ramblings/do-an-imperfect-thing-to-improve-what-you-want/): This is a perspective. Because I want to do things well, and thoroughly, but am not 100% all the time,... - [Obsidian Smart Composer is Fucking Awesome](https://testy.cool/notes/obsidian-smart-composer-is-fucking-awesome/): Someone made a plugin called "Obsidian Smart Composer" that works similar to Cursor or Github Copilot, and other AI assistants... - [YT Stop Recommending Me Shit I Don't Care About](https://testy.cool/ramblings/yt-stop-recommending-me-shit-i-dont-care-about/): I put so much effort into my YT feed or whatever it's called. I use PocketTube (excellent extension btw) to... - [I Keep Getting Distracted And Simple Tasks Take Way Longer Than They Should](https://testy.cool/ramblings/i-keep-getting-distracted-and-simple-tasks-take-way-longer-than-they-should/): I keep drifting from one thing to the other. They seem somewhat related. But I end up branching off to... - [When Listening, My Default Setting is Projecting](https://testy.cool/ramblings/when-listening-my-default-setting-is-projecting/): I think I have to make an effort to listen to the other person's speech, and try to work with... - [Quarto Icons & Extension Path Resolution](https://testy.cool/today-i-learned/quarto-icons-extension-path-resolution/): Quarto extensions like iconify can be installed using: quarto add mcanouil/quarto-iconify This creates an _extensions directory in your project root... - [How to Remove Empty Image Placeholders from Quarto Listings](https://testy.cool/today-i-learned/how-to-remove-empty-image-placeholders-from-quarto-listings/): The Problem By default, Quarto's listing pages show thumbnails for each post. Even if you don't have images, it still... - [Setting up Obsidian with the Obsidianite Theme and Smart Composer Plugin](https://testy.cool/tutorials/setting-up-obsidian-with-the-obsidianite-theme-and-smart-composer-plugin/): I recently recorded a quick walkthrough of how I set up a fresh Obsidian vault. My goal isn't complexity; I... - [Using Custom MDI Icons in Astro Starlight Card Components](https://testy.cool/today-i-learned/using-custom-mdi-icons-in-astro-starlight-card-components/): By default you can only use built-in icons in cards in Astro Starlight. Like this: - ✨ Some text here... - [Undid a commit and lost a bunch of posts I was excited about](https://testy.cool/today-i-learned/undid-a-commit-and-lost-a-bunch-of-posts-i-was-excited-about/): Update: This blog is currently in WordPress because having it in Astro meant I had to tinker a lot more... --- # # Detailed Content ## Pages ### Online Jupyter Notebook to HTML or PDF Converter - Published: 2025-05-07 - Modified: 2025-05-07 - URL: https://testy.cool/online-jupyter-notebook-to-html-or-pdf-converter/ This tool converts Jupyter Notebooks (. ipynb files) into formatted HTML or PDF documents entirely in your browser. You can read more about how it works below. Jupyter Notebook to HTML Converter Drag & Drop or Click to Upload . ipynb files only Processing... document. addEventListener('DOMContentLoaded', => { const dropZone = document. getElementById('dropZone'); const fileInput = document. getElementById('fileInput'); const preview = document. getElementById('preview'); const errorDiv = document. getElementById('error'); const loading = document. getElementById('loading'); // Initialize renderer const renderNotebook = window. ipynb2html. createRenderer(document); // Handle file selection const handleFile = file => { errorDiv. style. display = 'none'; loading. style. display = 'block'; const reader = new FileReader; reader. onload = async (e) => { try { const notebook = JSON. parse(e. target. result); preview. innerHTML = ''; const rendered = renderNotebook(notebook); preview. appendChild(rendered); } catch (error) { errorDiv. textContent = `Error: ${error. message}`; errorDiv. style. display = 'block'; } finally { loading. style. display = 'none'; } }; reader. onerror = => { errorDiv. textContent = 'Error reading file'; errorDiv. style. display = 'block'; loading. style. display = 'none'; }; reader. readAsText(file); }; // Drag & Drop handlers dropZone. addEventListener('dragover', (e) => { e. preventDefault; dropZone. classList. add('dragover'); }); dropZone. addEventListener('dragleave', => { dropZone. classList. remove('dragover'); }); dropZone. addEventListener('drop', (e) => { e. preventDefault; dropZone. classList. remove('dragover'); const files = e. dataTransfer. files; if (files. length > 0 && files. name. endsWith('. ipynb')) { handleFile(files); } }); // File input handler fileInput. addEventListener('change', (e) => { if (e. target. files)... --- ### Tools - Published: 2025-05-06 - Modified: 2025-05-06 - URL: https://testy.cool/tools/ Various tools that I've coded in HTML/JS. Chrome Extension Icon Generator A quick way to generate icons for chrome extensions. Just upload the image and it'll instantly display the 4 resized variants, converted to . png , your browser will also download a . zip containing them with the appropriate names, and you'll also have the manifest code available to copy/paste. Check it out --- ### Chrome Extension Icon Generator - Published: 2025-05-06 - Modified: 2025-05-06 - URL: https://testy.cool/chrome-extension-icon-generator/ For when you're excited about the Chrome Extension you just vibe-coded, but you realize that you just got the most boring error ever - "Could not load extension icon" How it works: Upload any image (PNG/JPG) ≥128x128px It will instantly create 4 required sizes Download ready-to-use icons + manifest code I don't ever see what you upload. Your image never leaves your browser - zero server processing. Chrome Extension Icon Generator Click to Upload or Drag Image Here (Minimum 128×128px) Waiting for image... Manifest Code // Your code will appear here document. addEventListener('DOMContentLoaded', => { const sizes = ; let currentImage = null; const dropZone = document. querySelector('. drop-zone'); // Handle both click and drag/drop function handleImage(file) { const reader = new FileReader; reader. onload = (e) => { const img = new Image; img. onload = => { if(img. width < 128 || img. height < 128) { alert('Please use image ≥128px in both dimensions'); return; } currentImage = img; document. getElementById('generateBtn'). disabled = false; document. getElementById('generateBtn'). textContent = ' Generate Icons'; }; img. src = e. target. result; }; reader. readAsDataURL(file); } // Click handler document. getElementById('fileInput'). addEventListener('change', (e) => { if(e. target. files) handleImage(e. target. files); }); // Drag/drop handlers dropZone. addEventListener('dragover', (e) => { e. preventDefault; dropZone. style. borderColor = '#2196f3'; }); dropZone. addEventListener('dragleave', => { dropZone. style. borderColor = 'inherit'; }); dropZone. addEventListener('drop', (e) => { e. preventDefault; dropZone. style. borderColor = 'inherit'; if(e. dataTransfer. files) handleImage(e. dataTransfer. files); }); // Generate icons document. getElementById('generateBtn').... --- ### Blog - Published: 2025-05-04 - Modified: 2025-05-04 - URL: https://testy.cool/blog/ Pellentesque tincidunt tristique neque, eget venenatis enim gravida quis. Fusce at egestas libero. Cras convallis egestas ullamcorper suspens. --- ### Contact - Published: 2025-05-04 - Modified: 2025-05-04 - URL: https://testy.cool/contact/ I'm always happy to connect. Whether it's feedback, questions, or suggestions. You can send me an email at right@testy. cool. I'll get back to you as soon as I can. You can also find me on social media and GitHub: X/Twitter: @testy_cool Bluesky: @testycool Github: @testy-cool --- ### Privacy Policy - Published: 2025-05-04 - Modified: 2025-05-04 - URL: https://testy.cool/privacy-policy-2/ Effective Date: May 4th 2025 This Privacy Policy describes how TestyCool ("we," "us," or "our") collects, uses, and discloses your personal information when you visit, use, or make a comment on https://testy. cool By using the Website, you agree to the collection and use of information in accordance with this policy. 1. Information We Collect We collect information about you in various ways when you use the Website: Information You Provide Directly: Comments: When you leave a comment, we collect the information you provide, including your name (or chosen username), email address, and the content of your comment. Your email address is stored but not publicly displayed. Information Collected Automatically: Usage Data: We automatically collect certain information about your device and how you interact with the Website. This includes your IP address, browser type, operating system, referring URLs, pages viewed, time spent on pages, and other diagnostic data. Cookies and Tracking Technologies: We use cookies and similar tracking technologies to track activity on our Website and hold certain information. Comment Login Cookies: If you log in to leave a comment, cookies may be used to remember your login status for convenience. Analytics Cookies: We use cookies provided by Google Analytics to collect information about how visitors use our site. This data helps us understand traffic patterns and improve the Website. Server Logs: Our web server automatically records information when you visit the Website, including your IP address, browser type, the page you visited, and the time of your visit. 2.... --- ### About - Published: 2022-02-23 - Modified: 2025-05-05 - URL: https://testy.cool/about/ Pellentesque tincidunt tristique neque, eget venenatis enim gravida quis. Fusce at egestas libero. Cras convallis egestas ullamcorper suspens. Trying to make LLMs do useful things. Focusing on practical AI workflows and getting stuff done. Currently consulting in AI (LLMs at scale) & automation to save time and money. Background in digital marketing, sysadmin, SEO, and product management. I try to see the whole picture, from server metal to making users happy (and making money). What I Do Develop LLM solutions that reduce costs and save time Create websites that rank well and generate revenue Automate repetitive tasks with AI Research and implement cost-effective solutions Fine-tune LLMs for specific business needs Build scalable e-commerce and SaaS platforms Experience AI strategy, LLMs at scale, automation, observability (Langfuse) & evals (Langfuse and own tools) Developing AI pipelines for bulk text generation Built and sold a hosting company Built profitable affiliate websites Tech Stack Python (data processing, web scraping, automation) Large Language Models (OpenAI, Claude, Gemini, OpenRouter, etc. ) AI Agent Frameworks (OpenAI Agents, Langgraph, Pydantic AI, SmolAgents) WordPress (business-focused development with a dash of aesthetics ) Modern Web (Next. js, React, Tailwind) Infrastructure (Linux, Coolify, cloud platforms) Databases (SQL, NoSQL) AI/ML tools and frameworks Contact Always open talking to people doing cool things. Hit me up if you want to chat about reliable AI systems, agents, evals, SEO, or building stuff. --- --- --- ## Posts ### Fix Black/Gray Screen Issues with ShareX or Windows Screenshot Tools - Published: 2025-05-13 - Modified: 2025-05-13 - URL: https://testy.cool/notes/fix-black-gray-screen-issues-sharex-or-windows-screenshot-tools/ - Categories: Notes The Problem If you're experiencing these frustrating screen capture issues on Windows 10: ShareX showing only black screens when capturing Windows Snipping Tool displaying gray screens instead of your content The Solution A fix is to terminate the Desktop Window Manager (dwm. exe) process by running this command in PowerShell or Command Prompt with administrator rights: taskkill /f /im dwm. exe Executing this command should resolve the screen capture issues. Why This Works While Windows prevents you from actually killing the Desktop Window Manager (it's a critical system process), the attempt to terminate it seems to reset something in the display rendering pipeline that fixes the capture issues. Notes No need to restart your computer --- ### Web Scraping with Playwright Aria Snapshots in crawl4ai - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/tutorials/web-scraping-with-playwright-aria-snapshots-in-crawl4ai/ - Categories: Tutorials - Tags: crawl4ai, playwright, python, webscraping I recently came across Playwright's Aria Snapshots, when testing the Playwright MCP. As someone who regularly needs to extract data from websites, I'm always looking for more reliable ways to understand webpage structure. When I tried out Microsoft's Playwright MCP (Model Context Protocol) with the MCP boom, from a few months ago, I was impressed by how it used Aria Snapshots to navigate websites. It moved much better than any browser agent I had tested until that point. Here's the full script in a Github gist. What Are Aria Snapshots? Aria Snapshots provide a semantic representation of a webpage's accessibility tree - essentially showing the structure and relationships between elements in a way that assistive technologies (and now our scrapers) can understand. It's like getting a clean, hierarchical outline of a webpage that's much easier to parse than raw HTML. Why It's Interesting I've been using crawl4ai for my scraping projects, which already has good methods for converting content to Markdown. But after seeing how well Playwright MCP worked with GPT 4. 1, I wanted to integrate Aria Snapshots into my workflow. The JavaScript version of Playwright has had this feature for a while, but I was excited when Python support finally arrived in version 1. 52. Now it's available in crawl4ai. How It Works Here's a simple script that shows how to extract an Aria Snapshot using crawl4ai: import asyncio from typing import Any from crawl4ai import AsyncWebCrawler from playwright. async_api import Page import nest_asyncio nest_asyncio. apply # Define... --- ### The farther from the public or the money, the more bullshit I want to optimize - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/the-farther-from-the-public-or-the-money-the-more-bullshit-i-want-to-optimize/ - Categories: Ramblings - Tags: productivity I'm noticing that because I work "in the back", and what I produce doesn't feel like it will immediately be put in front of a user, it makes me want to optimize things that are more immediately influenced by me. Workflows mainly. I've been noticing this inclination for a long time and it's bad. Sometimes this has come in handy - specifically for some Cursor / Obsidian / Sublime Text related workflows. But I'd say that 90% of the things I feel the need to optimize are pointless. They just feel like it'll be something more robust. But a good part of me feels that optimizing workflows that don't affect the public facing product is tinkering and running away from the hard and boring work. --- ### Trying Image Upscalers & Enhancers - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/trying-image-upscalers-enhancers/ - Categories: Ramblings - Tags: fail Most image upscalers/enhancers I've found aren't great for with fine details. Image upscalers/enhancers won't do all the work if you don't know what you're doing. I was trying to upscale and enhance a photo for a billboard. The client didn't have a better one, and to get a new one there would be a bureaucracy involved. The last time I had tried upscalers was ~2 years ago, and figured they're really advanced and surely it'll solve my problem. But they didn't. Now it seems there's a ton of upscalers, because they're easy to implement, and you need to find the right one for the job. In my case, there were some blurred elements on the margins, and I didn't know I wanted them sharpened/enhanced in some way. The most sensible one is from TopazLabs. For my case they seemed like the most focused and intuitive upscaler, with some control, that doesn't degrade the quality of your image. I haven't tried all of them. Some notes: Canva seems to have some sort of app marketplace, and you can try out those apps and see which fits. This felt more time consuming than helpful. I would've loved to try Freepik. com's offering, but they don't have a free trial for upscaling. iloveimg. com made a reasonable effort. Picwish. com did a reasonable job because it made the parts that were bothering me sharper, which lead me to better understand what I needed to edit. I thought Replicate would be the best, since... --- ### Failed: Custom CSS in Glance Dashboard on Coolify - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/tutorials/failed-custom-css-in-glance-dashboard-on-coolify/ - Categories: Tutorials - Tags: fail I wanted to use a custom CSS theme for my Glance dashboard. The default font is JetBrains Mono, which is great for code, but not so great for reading. I wanted to use a custom CSS theme that is more readable. Glance is a modern, self-hosted dashboard application that aggregates content from various sources like RSS feeds, Reddit, Hacker News, YouTube, and GitHub into a single customizable interface. It features a widget-based system that lets you monitor everything from weather and stocks to server metrics and site status, all through a clean and minimal UI. The Setup I recently tried setting up Glance - a sleek dashboard app - using Coolify as my deployment platform. The basic setup was straightforward: create a new service in Coolify, point it to the Glance Docker image, and configure the basics. The Custom CSS Challenge Glance supports custom CSS through a configuration option in glance. yml: theme: custom-css-file: custom. css And Coolify provides volume mounting to persist files. In theory, this should be simple - mount a volume, add your CSS file, point Glance to it. In practice? Not so much. What I Tried First attempt: Put the CSS file directly in the service directory theme: custom-css-file: custom. css Then tried the full path approach: theme: custom-css-file: /user/assets/custom. css Moved server config around: server: host: 0. 0. 0. 0 port: 8080 assets-path: /user/assets Even tried creating a /static directory and putting the CSS there. Every attempt resulted in the same thing: a 404 error... --- ### Ask yourself 'Does this move the needle' while doing something - Published: 2025-05-05 - Modified: 2025-05-08 - URL: https://testy.cool/ramblings/ask-yourself-does-this-move-the-needle-while-doing-something/ - Categories: Ramblings - Tags: productivity Instead of getting lost into exploring some idea that probably only improves your workflow, and takes 30mins, after you explored some other idea that took 30mins, maybe ask yourself "does this move the needle? " Ask yourself, after I'm done doing this, will I still have to come back to reality and work on the actual work? Maye asking yourself this will result in you prioritizing the actual work that needs doing. And then you can finally have some time to yourself. --- ### Do an imperfect thing to improve what you want - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/do-an-imperfect-thing-to-improve-what-you-want/ - Categories: Ramblings - Tags: productivity This is a perspective. Because I want to do things well, and thoroughly, but am not 100% all the time, I avoid it. But if I think about it as doing something "imperfect" to improve myself, it lightens the load. I know it's just tricking my brain. But it seems like even the thought of "do something imperfect" is way less pressure. This way I can do imperfect things towards achieving some goals. --- ### Obsidian Smart Composer is Fucking Awesome - Published: 2025-05-05 - Modified: 2025-05-08 - URL: https://testy.cool/notes/obsidian-smart-composer-is-fucking-awesome/ - Categories: Notes - Tags: obsidian, obsidian-plugins Someone made a plugin called "Obsidian Smart Composer" that works similar to Cursor or Github Copilot, and other AI assistants in VSCode. Except this one works in Obsidian. And the UI feels very much like in Cursor, which is excellent! As opposed to other plugins that do similar things: the UI is very clean it's uncluttered - other plugins, like the one about embeddings (I forgot the name, 'Smart Notes'? ) this lets you focus. It doesn't add so much initial friction that you're fatigued before you even actually try it out. It does exactly what you expect it! I absolutely love it and will recommend it to everyone! Now people who don't use VSCode can adopt Obsidian (which is among the best note-taking apps), and use functionalities similar to Cursor. This is huge. What it's missing: An inline editor. I don't always use it in Cursor, but I would really like it. Autocomplete - if it had an autocomplete like Supermaven at least, or Codeium, it would be great. --- ### YT Stop Recommending Me Shit I Don't Care About - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/yt-stop-recommending-me-shit-i-dont-care-about/ - Categories: Ramblings - Tags: productivity I put so much effort into my YT feed or whatever it's called. I use PocketTube (excellent extension btw) to organize subscriptions, and possibly get browser notifications if I really want to get the latest from some channels. I get a dopamine hit when I click "Not interested" or "Don't recommend channel" from bullshit recommendations from channels with punchable face thumbnails and "THIS CHANGES EVERYTHING" titles. I especially get a kick out of it when they are very popular channels. I get that it's hard for them. I've seen lots of quality vids that just had a stupid insane shocked face thumbnail, just to grab attention. After which the video was very clear and calm. And yet, how many exceptions can you make? I'm tired of all the nasty, shitty, attention grabbing thumbnails and titles getting my heartbeat up. But I digress, the point is - I click "Not interested" or "Don't recommend channel" on a daily basis. And yet Youtube keeps shoving shit in my feed. Why the fuck do you keep shoving shit I don't care about in my feed, Youtube? --- ### I Keep Getting Distracted And Simple Tasks Take Way Longer Than They Should - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/i-keep-getting-distracted-and-simple-tasks-take-way-longer-than-they-should/ - Categories: Ramblings - Tags: productivity I keep drifting from one thing to the other. They seem somewhat related. But I end up branching off to the related thing (Thing 2), and then forget about the initial one (Thing 1). And from there I may branch out to other things (Things 2++). After which I return to Thing 2, feeling like I've explored it thoroughly, to then realize it was just a side quest that wasn't all that necessary. And in fact instead of spending 30 min - 1h on a side quest, I should've focused on Thing 1 entirely. --- ### When Listening, My Default Setting is Projecting - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/ramblings/when-listening-my-default-setting-is-projecting/ - Categories: Ramblings - Tags: communication I think I have to make an effort to listen to the other person's speech, and try to work with them, letting them take the lead in a brainstorming session. Otherwise, I think mine (and most people's) default setting is to project. It's easier to project because it's a sort of self-validation. It's akin to hearing what you want to hear and it's gratifying. But in the end the conversation feels empty and it feels like there's a disconnect left between you and the other person. Whereas if I make an effort to try to put myself in their shoes, I'll realize I don't have enough information to actually have informed thoughts about being in their shoes, which leads me to ask more questions. This results in them feeling (and actually being) listened to, and me feeling fulfilled because I actually connected with them. I would've wanted to connect with them when I was projecting as well, but that's a very ill informed attempt at listening. It's what I used to think listening was. --- ### Quarto Icons & Extension Path Resolution - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/today-i-learned/quarto-icons-extension-path-resolution/ - Categories: TIL - Tags: quarto Quarto extensions like iconify can be installed using: quarto add mcanouil/quarto-iconify This creates an _extensions directory in your project root with the extension files. The Problem Quarto resolves extension paths relative to each document's location instead of the project root: Works for files in root directory (index. qmd) Fails for files in subdirectories (posts/article. qmd, pages/about. qmd) Here's the directory structure: my-blog/ ├── _extensions/ # Created by quarto add │ └── mcanouil/ │ └── iconify/ ├── index. qmd Works (finds _extensions/mcanouil/iconify) ├── posts/ │ └── article. qmd Fails (looks for posts/_extensions/mcanouil/iconify) └── pages/ └── about. qmd Fails (looks for pages/_extensions/mcanouil/iconify) Attempted Solutions Project Configuration: Tried individual _quarto. yml files in each directory Tried absolute paths None of these resolved the path issue File System Solutions: Tried symlinks (requires admin privileges on Windows) Tried duplicating _extensions directory (didn't work for me, maybe I didn't copy it correctly) Working Solution: Font Awesome First, added Font Awesome to _quarto. yml: format: html: css: - https://cdnjs. cloudflare. com/ajax/libs/font-awesome/6. 5. 2/css/all. min. css Maybe adding the entire Font Awesome library affects website speed but at this point I honestly don't care. I wasted 4 hours on this already. Now I can finally use a custom icon in my navbar configuration: navbar: right: - text: "" href: https://bsky. app/profile/testycool. bsky. social Note: The Bluesky icon specifically requires Font Awesome 6. 5. 2 or newer. Earlier versions don't include it. --- ### How to Remove Empty Image Placeholders from Quarto Listings - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/today-i-learned/how-to-remove-empty-image-placeholders-from-quarto-listings/ - Categories: TIL The Problem By default, Quarto's listing pages show thumbnails for each post. Even if you don't have images, it still reserves space for them, creating unnecessary whitespace. The Solution In your listing page (e. g. , index. qmd), configure the listing like this: listing: type: default fields: image-placeholder: "" This: Uses default layout instead of table/grid Only shows the fields you want Sets empty image placeholder to remove the space Why It Works The key is image-placeholder: "". Without this, Quarto reserves space for thumbnails even when posts don't have images. Setting it to an empty string removes this space entirely. The fields list explicitly states what you want to show, giving you clean, text-only listings. --- ### Setting up Obsidian with the Obsidianite Theme and Smart Composer Plugin - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/tutorials/setting-up-obsidian-with-the-obsidianite-theme-and-smart-composer-plugin/ - Categories: Tutorials - Tags: ai-editor, obsidian I recently recorded a quick walkthrough of how I set up a fresh Obsidian vault. My goal isn't complexity; I prefer a setup that looks good with minimal effort and provides powerful features out-of-the-box. This post documents that process, focusing on the Obsidianite theme and the Smart Composer community plugin. The Obsidianite Theme: Aesthetics without Fuss First things first, let's change the default look. I'm a big fan of the "Obsidianite" theme by Benny Guo. You can install it by going to Settings > Appearance > Themes > Manage. Search for "Obsidianite" and click "Install and use". Why Obsidianite? Honestly, it's mostly about the bold fonts. They have this subtle but pleasing gradient effect that just makes headings and emphasized text pop. It also has nice horizontal separators (---) and generally feels polished without requiring me to spend hours tweaking CSS snippets. I want to take notes, not become a theme designer! Integrating AI with Smart Composer The real magic comes from the "Smart Composer" plugin by Heesu Suh (GitHub repository). This plugin provides an interface to various Large Language Models (LLMs) directly within Obsidian. To install it: Go to Settings > Community plugins. If it's your first time, you'll need to "Turn on community plugins". Be aware of the security implications, as with any third-party code. Click Browse, search for "Smart Composer". Click Install, then Enable. Configuring Smart Composer Once enabled, you'll find "Smart Composer" in the settings sidebar. This is where you configure your AI providers. API Keys... --- ### Using Custom MDI Icons in Astro Starlight Card Components - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/today-i-learned/using-custom-mdi-icons-in-astro-starlight-card-components/ - Categories: TIL By default you can only use built-in icons in cards in Astro Starlight. Like this: - Some text here And it will render like this: But you may want additional icons, that aren't built in. Like the android icon. And if you try to use custom icons, such as from https://github. com/natemoo-re/astro-icon, you'll find that you can't use them in that colored square near the heading. You can only use them outside, like this , at least I haven't found a way. The Solution My solution has been to take the existing Astro Starlight Card component and edit it to allow usage of custom icons such as mdi:help-circle-outline, from Material Design Icons. In your src/components, create a new filename IconCard. astro and paste this in: --- import { Icon } from 'astro-icon/components'; interface Props { title: string; icon: string; } const { title, icon } = Astro. props; --- . card { --sl-card-border: var(--sl-color-purple); --sl-card-bg: var(--sl-color-purple-low); border: 1px solid var(--sl-color-gray-5); background-color: var(--sl-color-black); padding: clamp(1rem, calc(0. 125rem + 3vw), 2. 5rem); flex-direction: column; gap: clamp(0. 5rem, calc(0. 125rem + 1vw), 1rem); } . card:nth-child(4n + 1) { --sl-card-border: var(--sl-color-orange); --sl-card-bg: var(--sl-color-orange-low); } . card:nth-child(4n + 3) { --sl-card-border: var(--sl-color-green); --sl-card-bg: var(--sl-color-green-low); } . card:nth-child(4n + 4) { --sl-card-border: var(--sl-color-red); --sl-card-bg: var(--sl-color-red-low); } . card:nth-child(4n + 5) { --sl-card-border: var(--sl-color-blue); --sl-card-bg: var(--sl-color-blue-low); } . title { font-weight: 600; font-size: var(--sl-text-h4); color: var(--sl-color-white); line-height: var(--sl-line-height-headings); gap: 1rem; align-items: center; } . card . icon { border: 1px solid var(--sl-card-border); background-color: var(--sl-card-bg); padding: 0.... --- ### Undid a commit and lost a bunch of posts I was excited about - Published: 2025-05-05 - Modified: 2025-05-05 - URL: https://testy.cool/today-i-learned/undid-a-commit-and-lost-a-bunch-of-posts-i-was-excited-about/ - Categories: TIL - Tags: regrets Update: This blog is currently in WordPress because having it in Astro meant I had to tinker a lot more with it, and decided it's not a priority now. Was a hard pill to swallow, but had to do it. I'm just setting up my blog with Astro and I'm partly vibe coding it. I'm editing the content for my Astro blog in Obsidian. By default, Obsidian has wiki-style links, like ] and Astro works with markdown links (suchasthis. com) So I swore up and down at Claude, while using it in in Cursor, and it couldn't fix it. I even added Playwright MCP, so it automatically can open a browser and check how it renders for itself. Eventually I have up and I said fuck it, I'll just change the Obsidian wiki style links to pure markdown links (yes, I could've done that from the start but I just had to make it difficult). BUT, before that, in a fit of rage, I undid all commits since I started this Wiki links endeavor, and mistakenly lost some articles I loved that I'll probably never get back. --- ---