https://www.joshcanhelp.com2022-01-04T00:00:00ZJosh Cunninghamjosh@joshcanhelp.comEleventy Custom Content Type Collections and Layouts2022-01-04T00:00:00Zhttps://www.joshcanhelp.com/eleventy-custom-content-type-collections/How-to on creating separate collections and layouts for a custom content type. In this case: cocktails!<p>I love a great cocktail. There's something magical about taking a poison that can power a car and make it taste like heaven.</p>
<p><img src="https://www.joshcanhelp.com/_images/2022/bartender.jpg" alt="" /></p>
<p>I've been keeping <a href="https://www.joshcanhelp.com/cocktails/">a list of cocktails</a> that I've made and a list of cocktails that I would like to make once I have the ingredients on hand. I kept them as little clusters of bullet points that I published in an app called Workflowy and just sent the link to anyone I happened to talk about it with. When I <a href="https://www.joshcanhelp.com/notes/">moved to Obsidian</a>, that online list went away but I still maintained the collection of recipes.</p>
<p>During some time away from work recently, it occurred to me that I could put off <em>countless</em> more important things if I just sat down and got this collection of recipes back online for the ~5 people that have the previous link. So I sat down and did just that.</p>
<p>I have not gone very deep with Eleventy since I <a href="https://www.joshcanhelp.com/taking-wordpress-to-eleventy/">converted this whole site earlier this year</a> and I was looking forward to getting to know the data cascade a little better. Most of what I've done on this blog was using <a href="https://www.11ty.dev/docs/data-frontmatter/">template front matter</a>, the blocks of data at the top of the <a href="https://raw.githubusercontent.com/joshcanhelp/josh-to-11/master/_content/post/2021/2021-11-01-taking-notes.md">Markdown files that get turned into posts</a>. Everything was defined in the content and there wasn't any reason to generate data of any kind.</p>
<p>But the content that made up these recipes was a bit different:</p>
<ul>
<li>The file names were the titles</li>
<li>Chronological order was not important</li>
<li>There were specific ingredients that I wanted to call out</li>
</ul>
<p>This, as well as the URL, all needed to be built programmatically so I wouldn't have to maintain any of those data blocks. I was also hoping I'd find a way to manage my post dates and URLs using their file name instead of explicitly in the front matter.</p>
<p>If you've worked in <a href="https://www.joshcanhelp.com/tag/wordpress/">WordPress</a> before then you're probably familiar with the concept of <a href="https://wordpress.org/support/article/post-types/#custom-post-types">custom post types</a>. These are developer-defined content types that can be edited and themed differently than the built-in posts and pages. They're great for unique content types like the ones I'm working with here and created the model that I needed in my head:</p>
<ul>
<li>I needed a single template file for individual content pieces of this type</li>
<li>I needed a page where they aggregate</li>
<li>I needed to parse the content for the ingredients that I wanted to display separately</li>
</ul>
<p>I started with a layout alias that pointed to an empty template file.</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// .eleventy.js</span><br /><br />eleventyConfig<span class="token punctuation">.</span><span class="token function">addLayoutAlias</span><span class="token punctuation">(</span><span class="token string">"cocktail"</span><span class="token punctuation">,</span> <span class="token string">"layouts/cocktail.njk"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>This would be the field I would look for when filtering the content into collections. This is not technically necessary but it gives us an easy way to answer the question "how should this content be handled" throughout our code.</p>
<p>Next, I added all the cocktails as Markdown files <a href="https://github.com/joshcanhelp/josh-to-11/tree/master/input/cocktails">in their own directory</a> in the main <code>input</code> directory where the rest of my content lives. A few things to call out here:</p>
<ul>
<li>The file names are Sentence Capitalized and function as the title for the page</li>
<li>Individual cocktails recipes are in a <code>made</code> or <code>next</code> directory, indicating whether I've made them or not</li>
<li>The <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/cocktails/made/Old%20Fashioned.md">individual recipes</a> have no front matter at all, everything is generated</li>
</ul>
<p>The magic here all happens in a <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/cocktails/cocktails.11tydata.js">template data file</a>. The docs are a little thin on this but there are two "levels" of data here:</p>
<ul>
<li>The top-level properties, like <code>layout</code> in the linked file above, are pulled as-is and used as defaults.</li>
<li>The properties under <code>eleventyComputed</code> are generated using template-specific data and will override all previous data.</li>
</ul>
<p>I set the <code>layout</code> to <code>"cocktail"</code> for everything in that directory and added <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/_includes/layouts/cocktail.njk">the layout file</a> to use. This layout looks pretty similar to <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/_includes/layouts/post.njk">the post layout</a> with one main difference: content is being passed through a <code>stripSquareBrackets</code> filter that <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/eleventy/filters.js#L20">strips out the brackets</a> my note-taking app, Obsidian, uses to link between local files. More on how these are used below.</p>
<p>So, we have a valid layout alias, content to work with, a layout to display that content, and a data file to tie it all together. Now it's time for the <code>eleventyComputed</code> magic!</p>
<p>The easiest was the <code>title</code> and <code>meta_title</code>. Those both come mostly as-is from the file name:</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// input/cocktails/cocktails.11tydata.js</span><br /><br />module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span><br /> <span class="token comment">// ... </span><br /> <span class="token literal-property property">eleventyComputed</span><span class="token operator">:</span> <span class="token punctuation">{</span><br /> <span class="token function-variable function">title</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> data<span class="token punctuation">.</span>page<span class="token punctuation">.</span>fileSlug<span class="token punctuation">,</span><br /> <span class="token function-variable function">meta_title</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> data<span class="token punctuation">.</span>page<span class="token punctuation">.</span>fileSlug <span class="token operator">+</span> <span class="token string">" Cocktail Recipe"</span><span class="token punctuation">,</span><br /> <span class="token comment">// ... </span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>That <code>data.page</code> object has some handy data from the file system as well as a few converted properties:</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span><br /> <span class="token comment">// From the file system:</span><br /> date<span class="token operator">:</span> <span class="token number">2021</span><span class="token number">-12</span>-12T01<span class="token operator">:</span><span class="token number">34</span><span class="token operator">:</span><span class="token number">32</span>.174Z<span class="token punctuation">,</span><br /> inputPath<span class="token operator">:</span> './input/cocktails/next/Yuletide Wave Punch.md'<span class="token punctuation">,</span><br /><br /> <span class="token comment">// Eleventy-generated</span><br /> fileSlug<span class="token operator">:</span> 'Yuletide Wave Punch'<span class="token punctuation">,</span><br /> filePathStem<span class="token operator">:</span> '/cocktails/next/Yuletide Wave Punch'<span class="token punctuation">,</span><br /> url<span class="token operator">:</span> '/cocktails/yuletide-wave-punch/'<span class="token punctuation">,</span><br /> outputPath<span class="token operator">:</span> '_dist/cocktails/yuletide-wave-punch/index.html'<br /><span class="token punctuation">}</span></code></pre>
<p>I used the <code>filePathStem</code> to figure out if the recipe was in the "made" group or not and added some content at the top of the recipe indicating it's status.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> madeIt <span class="token operator">=</span> data<span class="token punctuation">.</span>page<span class="token punctuation">.</span>filePathStem<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"/made/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>The permalink for the cocktail is built from the file name by replacing non-letter characters with dashes and lower-casing the whole string. You can also use the <code>data.page.url</code> value, appending <code>/index.html</code> at the end. I had a few additional characters to pull out so I went with my own regex.</p>
<p>Finally, I wanted something akin to tags here based on specific ingredients in the recipe. I <a href="https://www.joshcanhelp.com/notes/">use Obsidian</a> to manage almost everything I write, including these recipes. It lets you use double square brackets <code>[[Like This]]</code> to link to other, related files. In these recipes, I use them to tie cocktails together by ingredients and keep notes on the specific ingredients themselves.</p>
<p><img src="https://www.joshcanhelp.com/_images/2022/obsidian-linked-mentions.png" alt="" /></p>
<p>I'm not able to replicate that inter-linking from Obsidian on my blog (yet) but I <em>can</em> use that information to tie cocktail recipes together. The content of the recipe itself is not available in these data files but it's easy to read the contents of the file being processed using the built-in Node file system module <code>fs</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// input/cocktails/cocktails.11tydata.js</span><br /><br />module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span><br /> <span class="token comment">// ... </span><br /> <span class="token function-variable function">ingredients</span><span class="token operator">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token comment">// Get the absolute path to the file</span><br /> <span class="token keyword">const</span> filePath <span class="token operator">=</span> data<span class="token punctuation">.</span>page<span class="token punctuation">.</span>inputPath<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"relative path"</span><span class="token punctuation">,</span> __dirname<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token comment">// Read the file contents</span><br /> <span class="token keyword">const</span> fileContent <span class="token operator">=</span> <span class="token keyword">await</span> fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> <span class="token string">"utf8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token comment">// Find all the bracketed content</span><br /> <span class="token keyword">const</span> ingredients <span class="token operator">=</span> fileContent<span class="token punctuation">.</span><span class="token function">matchAll</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\[\[[\w\d\s]*\]\]</span><span class="token regex-delimiter">/</span><span class="token regex-flags">gm</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token comment">// Flatten the regex array and get rid of any duplicates</span><br /> <span class="token keyword">const</span> ingredientsFlat <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>ingredients<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">flat</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token comment">// Ditch the brackets</span><br /> <span class="token keyword">return</span> ingredientsFlat<br /> <span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">ingredient</span><span class="token punctuation">)</span> <span class="token operator">=></span> ingredient<br /> <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"[["</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"]]"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>This saves all the ingredients in brackets to an array that I can use to output on the page or find other cocktails that match.</p>
<blockquote class="warning-block"><p>The processing time for ~100 files was not visibly affected by reading the file content at least one extra time per file. If you start to get into the thousands of files, though, this might not be a viable solution. I read through several posts and issues and it was clear that this data had not been loaded by the time these data files are processed.</p>
</blockquote>
<p>At this point, we've got the individual cocktail recipes building their own pages but we need a list of cocktails separated by whether I've made them or now. For that, I used 2 <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/eleventy/collections.js#L54">custom collections</a> , <code>cocktailsMadeCollection</code> and <code>cocktailsNextCollection</code>, that use the <code>layout</code> property and the presence of the <code>made</code> folder to pull out the custom content types and sort into one or the other. The logic looks like this:</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// .eleventy.js</span><br /><br />module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> config<span class="token punctuation">.</span><span class="token function">addCollection</span><span class="token punctuation">(</span><span class="token string">"cocktailsMadeCollection"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">collection</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> collection<span class="token punctuation">.</span><span class="token function">getAllSorted</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">tpl</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> hasMadePath <span class="token operator">=</span> tpl<span class="token punctuation">.</span>filePathStem<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"/made/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> hasMadePath <span class="token operator">&&</span> <span class="token string">"cocktail"</span> <span class="token operator">===</span> tpl<span class="token punctuation">.</span>data<span class="token punctuation">.</span>layout<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>alphaSortTitle<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<p>The "I haven't made this" collection is the same except for the path being checked.</p>
<p>Last but not least, we need a layout to display these collections. With single pages, I always start with <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/pages/cocktails.md">a Markdown template</a> to make it easier to add any contextual content. I've had layout files with one-off content in HTML and it just ... <em>felt dirty</em>.</p>
<p>That template points to <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/_includes/layouts/cocktails.njk">this layout</a> which counts up and displays the two collections of recipes. The recipes are displayed with their ingredients compiled from the computed data.</p>
<p><strong>And that's that!</strong></p>
<p>I used what I learned to <a href="https://github.com/joshcanhelp/josh-to-11/blob/master/input/posts/posts.11tydata.js">dynamically handle some of the post data</a> as well. Managing posts is a bit easier and less to think about when I create new ones. This all came together quite easily, which is not surprising as that's been the case for the 2 years I've been using Eleventy. If you're looking to start writing on a static site or <a href="https://www.joshcanhelp.com/taking-wordpress-to-eleventy/">move over from WordPress</a>, I highly recommend it!</p>
<h2 class="hr" id="references">
<span class="pink"><</span>
References
<span class="pink">></span>
</h2>
<ul>
<li><a href="https://www.joshcanhelp.com/cocktails/">The full list of cocktails</a> and <a href="http://localhost:8080/cocktails/vaquero/">my favorite</a></li>
<li><a href="https://github.com/joshcanhelp/josh-to-11/pull/27/files">PR to add this whole system</a> and the <a href="https://github.com/joshcanhelp/josh-to-11/pull/28/files">PR to add all the recipes</a></li>
<li><a href="https://www.11ty.dev/docs/data-template-dir/">Eleventy docs on template data files</a></li>
<li><a href="https://www.11ty.dev/docs/collections/">Eleventy docs on collections</a></li>
<li><a href="https://benmyers.dev/blog/eleventy-data-cascade/">Run-down of the data cascade in Eleventy</a></li>
</ul>
Taking Notes: Why and How2021-11-01T00:00:00Zhttps://www.joshcanhelp.com/notes/I've been writing for myself regularly for probably 15 years and have tried out many different systems and apps. Recently, I think I finally found the right one.<p>I've been writing for myself regularly for probably 15 years or so. Whether it's journaling or taking notes while I learn something or just keeping references, I find both the act of taking notes and the output to be extremely valuable for me.</p>
<p><img src="https://www.joshcanhelp.com/_images/2021/taking-notes.jpg" alt="" /></p>
<p>Taking notes keeps me focused on the task or meeting or thought that I'm exploring and help me to save my place if it goes on for more than one session. I also find that it solidifies the experience in my head and helps to identify the important parts. After the activity itself, notes can provide an important record for myself and others if they get published somewhere. My notes often turn into posts and documentation on my site or internally (see <a href="https://training.kalzumeus.com/newsletters/archive/do-not-end-the-week-with-nothing">Patrick McKenzie's thoughts on producing artifacts</a>).</p>
<p>The more notes you take, though, the more "stuff" you have to look through when you need a reference in the future. I just recently spent a couple of days going through and cleaning up what I have and I was surprised by the number of similar notes and overlap that I found between all of the different places I've stored my writing. Once you've felt the pain of trying to find something you're sure that you wrote about, you might find it painful again to start a note on something in the future. You can feel yourself causing more pain in the future by writing more. That's not a good place to be in when you want/need to write and the cognitive load of "where do I put this so I can find it later" can stop you from even starting another note.</p>
<p>I wrote a long time ago about <a href="https://www.joshcanhelp.com/information-reservoirs-or-how-i-keep-track-of-a-large-amount-of-incoming-information/">information reservoirs</a> and it's still quite relevant for this notes problem. If you have a thought or a link or a picture you want to keep and find later, you want to think very little about where to put it. Part of reducing that thinking is knowing you can find it later, if not easily then just not too painfully. If everything you might save has a place and everything you do save can be found, this system works. It's a bit like Marie Kondo's philosophy of everything having a place: if you bring home something that does not have a place, then you either give it a place, you get rid of the thing, or you just start to build clutter.</p>
<p>I've been working on refining how I take and store notes, partly because I never felt settled into a system and partly because the number ways to do this seems to have expanded quite a bit recently. The idea of building and managing a "personal knowledge base" or PKB is something that I'm seeing more and more people writing about and, as such, I've been thinking about it a lot recently as well. I think everyone would benefit from getting their thoughts into words on a regular basis but I do acknowledge that maintaining this kind of system is one part productivity and one part hobby.</p>
<p>I've worked my way through a number of different systems and applications over time with varying levels of commitment and success. I think the one I just started using, <a href="https://obsidian.md/">Obsidian</a>, is as close to perfect as I've found and I'll explain why in a little walk-through video at the end.</p>
<p>I started with just text files in directories. I started writing notes before there was a big push towards storing your data online or in the cloud. This was also before you could be all that productive on your phone so note-taking on-the-go was reserved for only the most ... desperate. <a href="https://www.joshcanhelp.com/the-search-for-a-new-cell-phone/">My experience looking for a new phone in 2009</a> will help make the reasons why more clear. If I was writing for myself, I was on my desktop computer at home or a computer at school. I would save my notes to a USB, sync when I was home, and rely on my backups in case I lost the drive.</p>
<p>At some point someone turned me on to <a href="https://brettterpstra.com/projects/nvalt/">nvALT</a>, a small app for organizing your notes and seeing them all in one place. I think around the same time I started using Dropbox and the combination was somewhat mind-blowing. I started taking a lot more notes and saving more text snippets from sites and articles that I found. I felt like I was more efficient creating and finding my notes, so I started using it more. The app didn't sync anything anywhere, it just organized a bunch of text files that were stored in a certain directory so it wasn't much different from how I was doing it before.</p>
<p>I kept with this system for a long time because it worked and because it was simple. Apps like Evernote and OneNote and came out and I tried that but it just wasn't for me. I wanted mostly plain text stored locally.</p>
<p>Then someone told me about <a href="https://workflowy.com/a/">Workflowy</a> and I was, once again, totally blown away. Workflowy is basically one giant bullet point list that lets you focus in at any point of the tree. Imagine all of your notes and references and everything all in one massive document and then setting what amounts to bookmarks at places where you want to jump back in. I realized that 95% of my notes and references were bullet points and that the rest of my writing was just a bullet point list that didn't know it was a bullet point list yet (picture the HTML DOM). I had an honest-to-god revelation and realized that it's bullet points all the way down, man.</p>
<p><img src="https://www.joshcanhelp.com/_images/2021/html-dom-as-bullet-points.png" alt="" /></p>
<p>I started taking more notes than I ever have, saving recipes and code snippets and task lists and everything else. Between this paradigm shift/discovery and Workflowy's delightful interface, I felt like I had truly reached nirvana. When I stopped using it, I had a half-MB document containing almost 8,500 individual bullet points of notes, references, and tasks.</p>
<p>After a while, though, something didn't feel quite right. If everything could be represented as a list and all the lists were stored together in a hierarchy, you really can only put things in one place. By definition, a child bullet point can only have a single parent. You always have to find a place before you can add a new note, which means you have to kind of store a map of things in your head in order to organize this all effectively. And when it's time to add, say, a list of quotes from an article about code quality, you have to decide "does this go in the section of article notes so I can find all my notes in one place or in the section of notes about code quality?" It takes a lot of management time to make sure the system is working well.</p>
<p>But manage I did until I found <a href="https://roamresearch.com/">Roam Research</a>. Roam represented a revelation for many, many folks who take regular notes for many reasons, one of which being <a href="https://maggieappleton.com/bidirectionals">bi-directional linking</a>. When you make a link from one page to another, that link is two-way so you have an explicit link to one page and that linked-to page automatically links back. Roam goes even further and also keeps track of implicit links just by looking up all the places where you used the title of the page that you're on. Now, as you write, your system is making connections between the information without you having to do it on your own.</p>
<p>I loved this concept and felt like I had found a very important piece of the puzzle. Roam did another thing, though, that had just as profound of an impact on me and that was the idea of automatically creating daily note pages and being able to create notes in the future. This combined with automatically linking notes together means that I always have a place to put a note of any kind, the daily notes spot, and know that I can easily find that chunk of text later. Roam is also based on bullet points so my existing mental model was represented.</p>
<p>Roam Research is a very cool product and it advanced my note-taking ability and workflow greatly but two main problems - no local copy and a clunky user interface - made me feel unsure about migrating everything I had into it. That said, I have been using the heck out of Roam since May 2020 and have written more notes in that time than the 2-3 years previous combined. Bullet points, bi-directional linking, and daily notes were key to that productivity.</p>
<p>Then came <a href="https://obsidian.md/">Obsidian</a> and, for a variety of reasons, I'm pretty sure this is the app I'll stick with for many years to come. It has nearly all of the features of all the other apps I've used combined, along with an interface that gets out of my way almost completely. I now have almost 10MB of text that I've created accessible through this app making linking things together very powerful. Now that it's all in one place, the idea of a PKB is more salient than ever.</p>
<p>I walked through how I use Obsidian in the video below, hopefully that's helpful for folks looking to take their notes to another level or migrate in from another system. In the video, I cover:</p>
<ul>
<li>Daily notes and template for tasks, routines, and default note collection</li>
<li>Explicit linking when I think about it, implicit when I don't</li>
<li>Project notes and structure for periodic review and better note collections</li>
<li>Tags for lightweight grouping for paragraphs and bullet points</li>
<li>Book and article archiving and notes</li>
<li>Blog posts are symlinked so they can searched and referenced</li>
<li>Anything that is (or can be) text and could at all be useful in the future gets stored</li>
<li>Problems including quick collection on mobile and data in other systems</li>
</ul>
<p>Enjoy!</p>
<iframe width="650" height="367" src="https://www.youtube.com/embed/wXI1YVWJuhA?si=2j7-uDXP4Jw7hgJI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
<h2 class="hr" id="references">
<span class="pink"><</span>
References
<span class="pink">></span>
</h2>
<ul>
<li><a href="https://github.com/joshcanhelp/sample-obsidian-vault">Example Obsidian vault used in the video</a></li>
<li><a href="https://www.youtube.com/watch?v=7uuXbUGjRUw">Previous video walk-through is here</a>.</li>
<li><a href="https://nileswyler.medium.com/why-i-switched-a-deep-dive-into-roam-vs-obsidian-df1a394971ff">Great post that helped me make the move from Roam to Obsidian</a></li>
<li><a href="https://news.ycombinator.com/item?id=28894481">Hacker News thread with lots of comments about Obsidian, other note taking apps, and the PKB concept in general</a></li>
</ul>