This is a valid Atom 1.0 feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
<feed xmlns="http://www.w3.org/2005/Atom"
line 198, column 0: (3 occurrences) [help]
<p>For smaller Publ sites, the suggested configuration is to use <a href="ht ...
line 198, column 0: (3 occurrences) [help]
<p>For smaller Publ sites, the suggested configuration is to use <a href="ht ...
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:fh="http://purl.org/syndication/history/1.0"
xmlns:at="http://purl.org/atompub/tombstones/1.0">
<title>Publ</title>
<subtitle>A personal publishing system for the modern web</subtitle>
<link href="http://publ.beesbuzz.biz/feed" rel="self" />
<link href="http://publ.beesbuzz.biz/feed" rel="current" />
<link href="https://busybee.superfeedr.com" rel="hub" />
<link href="http://publ.beesbuzz.biz/blog/feed?date=2023-05" rel="prev-archive" />
<link href="http://publ.beesbuzz.biz/" />
<id>tag:publ.beesbuzz.biz,2020-01-07:_all</id>
<updated>2025-04-03T11:59:46-07:00</updated>
<entry>
<title>v0.7.40</title>
<link href="http://publ.beesbuzz.biz/blog/857-v0-7-40" rel="alternate" type="text/html" />
<published>2025-04-03T11:59:46-07:00</published>
<updated>2025-04-03T11:59:46-07:00</updated>
<id>urn:uuid:cb97094e-d3a7-5ba6-a1d9-0e1deee1782f</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>I just released v0.7.40, which allows easily overriding the image used on an <a href="http://publ.beesbuzz.biz/manual/api/115-Entry-objects#card">entry card</a>.</p>
]]>
</content>
</entry>
<entry>
<title>v0.7.39 released</title>
<link href="http://publ.beesbuzz.biz/blog/1042-v0-7-39-released" rel="alternate" type="text/html" />
<published>2025-03-03T22:25:47-08:00</published>
<updated>2025-03-03T22:25:47-08:00</updated>
<id>urn:uuid:96df1609-9016-5925-9e43-bdc73b2b3f1d</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>There’s been several minor releases of Publ, and it’s up to v0.7.39 now. Here’s what’s changed since v0.7.35:</p>
<ul>
<li>Fixed a bug with CSS templates erroneously entity-escaping quotes</li>
<li><code>entry.archive()</code> now elides the template-name if it’s the category default (matching <code>view.link()</code>)</li>
<li>Internal type-safety changes for the latest version of BeautifulSoup</li>
<li>Add <a href="http://publ.beesbuzz.biz/manual/formats/322-Entry-files#status"><code>Status: ATTACHMENT</code></a></li>
<li>Removed the background image rendering threadpool, as it was an artifact of an early design that ended up not being beneficial for real-world operation</li>
<li>(Hopefully) fixed an issue with the indexer ignoring attachments that have not yet been indexed</li>
<li>Fixed an issue with the permission error handling on the admin dashboard</li>
</ul>
<p>The only user-facing change is the <code>Status: ATTACHMENT</code> thing.</p>
]]>
</content>
</entry>
<entry>
<title>Authl v0.7.3</title>
<link href="http://publ.beesbuzz.biz/blog/771-Authl-v0-7-3" rel="alternate" type="text/html" />
<published>2025-01-23T22:08:14-08:00</published>
<updated>2025-01-23T22:08:14-08:00</updated>
<id>urn:uuid:18f52cec-c1cd-5d0a-af0b-6ee512ac4a1c</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>I’ve updated Authl to make it support the new-ish <code>profile</code> scope in Mastodon 4.3, which provides better login-flow UX.</p><p>If <code>profile</code> is unsupported it tries to fall back to the old <code>read:accounts</code> scope, which should keep it working on older Mastodon versions as well.</p><p>In theory it should also work with Pleroma/Akkoma (and anything else that speaks the Mastodon client API), although that functionality hasn’t been verified in quite some time. If someone else wants to take on the work of verifying that and fixing whatever’s broken, that would be greatly appreciated!</p>
]]>
</content>
</entry>
<entry>
<title>Publ + Pushl releases and a bunch of plans</title>
<link href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans" rel="alternate" type="text/html" />
<published>2025-01-05T19:25:49-08:00</published>
<updated>2025-01-05T19:25:49-08:00</updated>
<id>urn:uuid:448a6793-87ae-5753-bf62-2ac50f10867e</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>There’s been a few releases of both Publ (now on 0.7.35) and Pushl (now on 0.4.0). A pretty decent amount has changed!</p><p>Publ changes since 0.7.31:</p>
<ul>
<li>Fix some error handling issues causing an ISE</li>
<li>Add support for HTTP <code>Accept:</code>, properly allowing multiple templates with the same name and providing <a href="http://publ.beesbuzz.biz/manual/324-Templating-Guide#template-mapping">reasonable fallback behavior</a></li>
<li>Improve the <code>Content-Type</code> handling in general</li>
<li>Fix some markup-safe handling bugs</li>
</ul>
<p>Note that in order to upgrade to 0.7.35 you’ll also need to restrict your Python environment to use a Python version < 3.13; more on that in a bit.</p><p>Pushl changes since v0.3.5:</p>
<ul>
<li>Tidy up some code rot</li>
<li>Actually send an <code>Accept:</code> header</li>
<li>Removed lxml + Pingback support, which has never actually been useful</li>
</ul>
<p>So, let’s talk about these projects and some other related stuff.</p>
<h3 id="930_h3_1_Tech-debt"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h3_1_Tech-debt"></a>Tech debt</h3><p>Publ has quite a lot of tech debt.</p><p>Most of the testing is done in an ad-hoc smoke-testing manner, and this has sometimes made it difficult for me to work on new features. (Of course I also am the only person working on these features, so I only prioritize things that I personally need.)</p><h4 id="930_h4_2_Pony"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h4_2_Pony"></a>Pony</h4><p>One particular issue is that it relies heavily on <a href="https://ponyorm.com">Pony</a>. Pony is a great ORM for doing quick application prototyping stuff, but unfortunately it’s been a problem for quite some time:</p>
<ul>
<li>It makes proper unit testing significantly more difficult (it’s actually the main reason the testing is in such a sorry state right now)</li>
<li>New Python versions usually end up breaking its clever code generator (which is why Publ 0.7.35 requires you to restrict your Python version)</li>
<li>It never gained support for schema migrations (which, thankfully, Publ was designed to not need to begin with, but this hampers some of my other plans)</li>
<li>General community support just never really materialized</li>
</ul>
<p>To address many of these problems, I’ve been wanting to move to another database abstraction; I will most likely use <a href="https://www.sqlalchemy.org/">SQLAlchemy</a>. Whether I use its ORM or not is something I’m still trying to decide.</p><h4 id="930_h4_3_Whoosh"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h4_3_Whoosh"></a>Whoosh</h4><p>Similarly, full-text search uses <a href="https://pypi.org/project/Whoosh/">whoosh</a>, which has been more or less abandoned. I have updated to use <a href="https://pypi.org/project/Whoosh-Reloaded/">whoosh-reloaded</a>, a community fork that has fixed most of the more egregious issues, but there are still a lot of issues with it:</p>
<ul>
<li>Its locking behavior is difficult to work with (and can cause a lot of operational difficulty)</li>
<li>Its ingest is slow and not easily threadable</li>
<li>Updating the index can be difficult and fragile</li>
<li>It stores the index on the local filesystem which can be a problem for many deployment scenarios</li>
<li>It puts <em>way</em> too much structured into its structured queries, and is overkill for the kinds of query representation Publ needs</li>
</ul>
<p>Unfortunately there aren’t as many existing full-text search implementations for Python. My expectation for now is that I’ll roll my own using the algorithms described in <a href="https://bart.degoe.de/building-a-full-text-search-engine-150-lines-of-code/">Bart de Goede’s article</a>, although this doesn’t feel like a great way to do things either.</p><h4 id="930_h4_4_Misaka"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h4_4_Misaka"></a>Misaka</h4><p>Finally, the Markdown engine currently used by Publ has been abandoned and is unlikely to continue to working in the long term. It’s always been a bit of an operational problem, as well, because it relies on Hoedown (which has been abandoned for ages and never even got updated with HTML 5 support) and requires being able to either retrieve architecture-specific binaries or being able to build them yourself. The build process has been <em>mostly</em> easy for most users, but it’s still not ideal.</p><p>Fortunately, I’ve been playing with other Markdown implementations on other projects, and I’m fairly certain that I’ll be happy with <a href="https://github.com/lepture/mistune">Mistune</a> instead. Switching to that will require reimplementing a bunch of stuff in Publ, but it’s all stuff I’d been wanting to fix anyway.</p><p>In particular, I’ve been wanting to figure out a way to templatize footnotes (for example, letting people make use of <a href="https://edwardtufte.github.io/tufte-css/">Tufte sidenotes</a> or putting a <code><details></code> reveal inline or after the current paragraph or the like), and there’s a lot that could be better about how image sets are currently handled, and ideally I’d be able to templatize those as well.</p><h3 id="930_h3_5_Comments"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h3_5_Comments"></a>Comments</h3><p>The main ways that I’ve handled comments on Publ-based sites is either:</p>
<ul>
<li><a href="https://webmention.io/">webmention.io</a> + <a href="https://github.com/PlaidWeb/webmention.js">webmention.js</a></li>
<li><a href="https://isso-comments.de">isso</a></li>
</ul>
<p>Both of these are Fineā¢ for simple usage but they run into a bunch of issues on larger sites, and also the UX just isn’t really where I’d like it to be.</p><p>I wrote a <a href="https://beesbuzz.biz/blog/7457-Some-thoughts-on-comments">much more detailed blog post</a> on my main site, but the short version is that I’d like to make a comment system that works more closely with Publ (or any other publishing framework) that stores things locally and supports both local posts <em>and</em> webmention (both sending and receiving), and which would also accept user data from the publishing stack.</p><p>I’m thinking it would take the form of a Python library that you can embed into an app (with easy hooks for Flask), but would also offer its own Flask frontend for hosting it as an embeddable app instance that can be used from non-Python things.</p><h3 id="930_h3_6_ActivityPub"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h3_6_ActivityPub"></a>ActivityPub</h3><p>Native ActivityPub support has been at the back of my mind for a while. Having its own built-in webmention endpoint would also make for a nice spot to start adding in ActivityPub, since ActivityPub verbs aren’t fundamentally different from Webmention verbs.</p><p>The main thing this would bring to the table is being able to set up various outboxes for different views (for example, <code>@blog@example.com</code> for just blog posts or <code>@all@example.com</code> for everything), and then also being able to make use of the user permissions to send private entries as DMs to the authorized subscribers, reducing the need for private entry stubs (which are bad UX all around and which I only adopted as a compromise because <a href="http://publ.beesbuzz.biz/blog/1266-Why-Publ-wont-support-magic-auth-links">magic links have problems</a> and feed readers <em>still</em> don’t support bearer tokens or <a href="https://indieweb.org/Ticketing_for_IndieAuth">Ticket Auth</a>).</p><h3 id="930_h3_7_Documentation"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h3_7_Documentation"></a>Documentation</h3><p>Also, having had to actually consult the docs while building a new Publ-based website, I’ve come to realize just how bad a disaster the <a href="http://publ.beesbuzz.biz/manual/">manual</a> currently is. It could really do with some reorganization at the very least.</p><h3 id="930_h3_8_In-conclusion"><a href="http://publ.beesbuzz.biz/blog/930-Publ-Pushl-releases-and-a-bunch-of-plans#930_h3_8_In-conclusion"></a>In conclusion</h3><p>I have a lot of stuff I want to work on and hopefully I get somewhere with some of these things this year. If you’d like to help out, you can make code contributions, or you can make financial contributions via <a href="https://ko-fi.com/fluffycritter">Ko-Fi</a>, <a href="https://patreon.com/fluffy">Patreon</a>, or <a href="https://github.com/sponsors/fluffy-critter">GitHub Sponsors</a>. But no pressure.</p>
]]>
</content>
</entry>
<entry>
<title>Publ v0.7.31 released</title>
<link href="http://publ.beesbuzz.biz/blog/569-v0-7-31-released" rel="alternate" type="text/html" />
<published>2024-10-02T02:13:22-07:00</published>
<updated>2024-10-02T02:13:22-07:00</updated>
<id>urn:uuid:7d73cb31-dd0c-537b-9f47-07c45ba77692</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>There’s a new release of Publ. There’s no new features, but there’s a <em>huge</em> performance improvement.</p><p>I’d been having some performance issues where on my larger sites, the main Atom feed was taking a long time to render. It didn’t really bother me too much because thanks to aggressive caching it would only cause an occasional slow page load (on the order of a few seconds) every now and then, but I thought there was probably something wrong with the I/O characteristics of how pages render.</p><p>Boy <em>howdy</em> was I wrong about that.</p>
<p>The way that Publ handles count-based pagination is to look at the first eligible entry and then traverse forward in the query results until it finds that number of visible ones. There’s a few other fancy things for handling the presence of unauthorized entries for various purposes (for example, <a href="http://publ.beesbuzz.biz/manual/api/150-View-object#has_unauthorized"><code>view.has_unauthorized</code></a> and being able to retrieve a limited number of unauthorized entries for friends-only stubs on feeds and so on), but the prevailing assumption was that PonyORM would just have a query result cursor page through every time the iterator incremented on the loop.</p><p>Turns out that, no. No it doesn’t.</p><p>In fact, what was happening was Pony ends up retrieving <em>every</em> possible entry first, before Publ’s auth filtering could run. So on <a href="https://beesbuzz.biz/">my main site</a>, for example, which has around 3300 entries, it was retrieving all 3300 entry rows in order to render the Atom feed.</p><p>So, yeah, no wonder it was taking multiple seconds to render!</p><p>Anyway, now in those situations, Publ just fetches chunks of entries at a time, basically doing its own ad-hoc cursor. It’s not quite as efficient as it would be with a proper database cursor (since now it’s using <code>LIMIT</code>/<code>OFFSET</code> queries) and it could still be way faster if I were using a database layer other than Pony (for example, switching to SQLAlchemy, or eschewing a database entirely as I’ve <a href="http://publ.beesbuzz.biz/blog/274-Publ-v0-7-26-released">briefly discussed</a> and <a href="https://beesbuzz.biz/code/3635-Making-a-hash-of-data">rambled</a> about), but wow, this makes a huge performance improvement overall.</p><p>Also, while I was trying to diagnose the issue, I had followed a red-herring path about changing the way that entry auth is stored, and ended up simplifying it in a way which is how I should have done it to begin with. Unfortunately that required a schema change, which means sites need to be reindexed after upgrading. Fortunately that’s still a largely transparent operation.</p><p>Someday I need to do some pretty big overhauls to Publ. But for now I’m happy just keeping it going and making it better all the time.</p><p>Anyway, <strong><em>huge</em></strong> thanks to BearPerson from eevee’s discord for having the curiosity and tenacity to find the <em>actual</em> performance issue.</p>
]]>
</content>
</entry>
<entry>
<title>Publ v0.7.30</title>
<link href="http://publ.beesbuzz.biz/blog/39-Publ-v0-7-30" rel="alternate" type="text/html" />
<published>2024-09-06T23:02:27-07:00</published>
<updated>2024-09-06T23:02:27-07:00</updated>
<id>urn:uuid:0dcd4668-3a8a-51aa-8a69-72f0bbd3e256</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>It’s been a while since I’ve worked on Publ but I got an itch for some new features, so here we are.</p><p>Specifically, there are two super-useful changes:</p>
<ul>
<li>You can now <a href="http://publ.beesbuzz.biz/manual/324-Templating-Guide#get-entry">retrieve a specific entry from a template</a> (by entry ID, not by path)</li>
<li>Given an existing <code>entry</code>, <code>category</code>, or <code>template</code> object you can retrieve an image relative to their context, using <a href="http://publ.beesbuzz.biz/manual/api/115-Entry-objects#func-image"><code>entry.image</code></a>, <a href="http://publ.beesbuzz.biz/manual/api/170-Category-objects#func-image"><code>category.image</code></a> and <a href="http://publ.beesbuzz.biz/manual/api/416-Template-object#func-image"><code>template.image</code></a>, respectively</li>
</ul>
]]>
</content>
</entry>
<entry>
<title>Publ 0.7.29 released</title>
<link href="http://publ.beesbuzz.biz/blog/843-Publ-0-7-29-released" rel="alternate" type="text/html" />
<published>2024-07-11T14:26:20-07:00</published>
<updated>2024-07-11T14:26:20-07:00</updated>
<id>urn:uuid:aa3e0f44-9064-58ef-bd07-a8b1252d99e3</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>Just a couple of bugfixes in this one:</p>
<ul>
<li>Fixed installing Publ without Authl</li>
<li><code>view.deleted</code> works on paginated views again</li>
<li>Updated upstream dependencies and fixed some typing-related stuff caused by that</li>
</ul>
]]>
</content>
</entry>
<entry>
<title>Using MySQL/MariaDB as your backing store</title>
<link href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store" rel="alternate" type="text/html" />
<published>2024-07-05T11:45:08-07:00</published>
<updated>2024-07-05T11:45:08-07:00</updated>
<id>urn:uuid:f9569d5a-44b7-549f-b536-1de795fdd8d7</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>How to use MySQL as the index database</p>
<p>For smaller Publ sites, the suggested configuration is to use <a href="https://sqlite.org/">SQLite</a> for the index database, as it is low-maintenance and performs very well due to being in-process and taking advantage of the operating system’s disk cache.</p><p>However, sometimes it’s helpful to use a larger-scale database system for the deployment, primarily to gain access to finer-grained locking. This is especially useful in situations where there are many thousands of entries and a desire to keep the site running at full capacity during a reindex.</p><p>Here is a configuration snippet that allows you to use MySQL/MariaDB on your Publ site:</p><figure class="blockcode"><figcaption>app.py</figcaption><pre class="highlight" data-language="python" data-line-numbers><span class="line" id="e764cb1L1"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L1"></a><span class="line-content"><span class="c1"># ...</span></span></span>
<span class="line" id="e764cb1L2"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L2"></a><span class="line-content"></span></span>
<span class="line" id="e764cb1L3"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L3"></a><span class="line-content"><span class="k">if</span> <span class="s1">'DATABASE_URL'</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">:</span></span></span>
<span class="line" id="e764cb1L4"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L4"></a><span class="line-content"> <span class="kn">import</span><span class="w"> </span><span class="nn">urllib.parse</span></span></span>
<span class="line" id="e764cb1L5"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L5"></a><span class="line-content"> <span class="n">parsed</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">'DATABASE_URL'</span><span class="p">])</span></span></span>
<span class="line" id="e764cb1L6"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L6"></a><span class="line-content"> <span class="n">user</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s1">'(.*):(.*)@(.*)'</span><span class="p">,</span> <span class="n">parsed</span><span class="o">.</span><span class="n">netloc</span><span class="p">)</span></span></span>
<span class="line" id="e764cb1L7"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L7"></a><span class="line-content"> <span class="n">db_config</span> <span class="o">=</span> <span class="p">{</span></span></span>
<span class="line" id="e764cb1L8"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L8"></a><span class="line-content"> <span class="s1">'provider'</span><span class="p">:</span> <span class="n">parsed</span><span class="o">.</span><span class="n">scheme</span><span class="p">,</span></span></span>
<span class="line" id="e764cb1L9"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L9"></a><span class="line-content"> <span class="s1">'user'</span><span class="p">:</span> <span class="n">user</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span></span></span>
<span class="line" id="e764cb1L10"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L10"></a><span class="line-content"> <span class="s1">'password'</span><span class="p">:</span> <span class="n">user</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span></span></span>
<span class="line" id="e764cb1L11"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L11"></a><span class="line-content"> <span class="s1">'host'</span><span class="p">:</span> <span class="n">user</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span></span></span>
<span class="line" id="e764cb1L12"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L12"></a><span class="line-content"> <span class="s1">'database'</span><span class="p">:</span> <span class="n">parsed</span><span class="o">.</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span></span></span>
<span class="line" id="e764cb1L13"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L13"></a><span class="line-content"> <span class="c1"># charset and collation must be specified, as the MySQL defaults do</span></span></span>
<span class="line" id="e764cb1L14"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L14"></a><span class="line-content"> <span class="c1"># not properly support emoji and other 4-byte characters</span></span></span>
<span class="line" id="e764cb1L15"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L15"></a><span class="line-content"> <span class="s1">'charset'</span><span class="p">:</span> <span class="s1">'utf8mb4'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb1L16"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L16"></a><span class="line-content"> <span class="s1">'collation'</span><span class="p">:</span> <span class="s1">'utf8mb4_bin'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb1L17"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L17"></a><span class="line-content"> <span class="p">}</span></span></span>
<span class="line" id="e764cb1L18"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L18"></a><span class="line-content"><span class="k">else</span><span class="p">:</span></span></span>
<span class="line" id="e764cb1L19"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L19"></a><span class="line-content"> <span class="n">db_config</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'provider'</span><span class="p">:</span> <span class="s1">'sqlite'</span><span class="p">,</span> <span class="s1">'filename'</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">APP_PATH</span><span class="p">,</span> <span class="s1">'index.db'</span><span class="p">)}</span></span></span>
<span class="line" id="e764cb1L20"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L20"></a><span class="line-content"></span></span>
<span class="line" id="e764cb1L21"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L21"></a><span class="line-content"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span></span></span>
<span class="line" id="e764cb1L22"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L22"></a><span class="line-content"> <span class="s1">'database_config'</span><span class="p">:</span> <span class="n">db_config</span><span class="p">,</span></span></span>
<span class="line" id="e764cb1L23"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb1L23"></a><span class="line-content"> <span class="c1"># ...</span></span></span>
</pre></figure><p>Then when running the site, set an environment variable such as:</p><figure class="blockcode"><pre><span class="line"><span class="line-content">DATABASE_URL='mysql://username:password@server/dbname'</span></span>
</pre></figure><p>If migrating from SQLite to MySQL, it is a good idea to create the index first before flipping the configuration:</p><figure class="blockcode"><pre><span class="line"><span class="line-content">DATABASE_URL='mysql://username:password@server/dbname' poetry run flask publ reindex</span></span>
</pre></figure><p>An alternate way to store the database configuration is to put it into a local <code>db_config.py</code> file, like so:</p><figure class="blockcode"><figcaption>db_config.py</figcaption><pre class="highlight" data-language="python" data-line-numbers><span class="line" id="e764cb4L1"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L1"></a><span class="line-content"><span class="n">db_config</span> <span class="o">=</span> <span class="p">{</span></span></span>
<span class="line" id="e764cb4L2"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L2"></a><span class="line-content"> <span class="s1">'provider'</span><span class="p">:</span> <span class="s1">'mysql'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L3"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L3"></a><span class="line-content"> <span class="s1">'user'</span><span class="p">:</span> <span class="s1">'db username'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L4"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L4"></a><span class="line-content"> <span class="s1">'password'</span><span class="p">:</span> <span class="s1">'db password'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L5"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L5"></a><span class="line-content"> <span class="s1">'host'</span><span class="p">:</span> <span class="s1">'localhost'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L6"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L6"></a><span class="line-content"> <span class="s1">'database'</span><span class="p">:</span> <span class="s1">'my_site'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L7"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L7"></a><span class="line-content"> <span class="s1">'charset'</span><span class="p">:</span> <span class="s1">'utf8mb4'</span><span class="p">,</span></span></span>
<span class="line" id="e764cb4L8"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L8"></a><span class="line-content"> <span class="s1">'collation'</span><span class="p">:</span> <span class="s1">'utf8mb4_bin'</span></span></span>
<span class="line" id="e764cb4L9"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb4L9"></a><span class="line-content"><span class="p">}</span></span></span>
</pre></figure><figure class="blockcode"><figcaption>app.py</figcaption><pre class="highlight" data-language="python" data-line-numbers><span class="line" id="e764cb5L1"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L1"></a><span class="line-content"><span class="c1"># ...</span></span></span>
<span class="line" id="e764cb5L2"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L2"></a><span class="line-content"></span></span>
<span class="line" id="e764cb5L3"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L3"></a><span class="line-content"><span class="k">try</span><span class="p">:</span></span></span>
<span class="line" id="e764cb5L4"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L4"></a><span class="line-content"> <span class="kn">from</span><span class="w"> </span><span class="nn">.db_config</span><span class="w"> </span><span class="kn">import</span> <span class="n">db_config</span></span></span>
<span class="line" id="e764cb5L5"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L5"></a><span class="line-content"><span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span></span></span>
<span class="line" id="e764cb5L6"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L6"></a><span class="line-content"> <span class="n">db_config</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'provider'</span><span class="p">:</span> <span class="s1">'sqlite'</span><span class="p">,</span> <span class="s1">'filename'</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">APP_PATH</span><span class="p">,</span> <span class="s1">'index.db'</span><span class="p">)}</span></span></span>
<span class="line" id="e764cb5L7"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L7"></a><span class="line-content"></span></span>
<span class="line" id="e764cb5L8"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L8"></a><span class="line-content"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span></span></span>
<span class="line" id="e764cb5L9"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L9"></a><span class="line-content"> <span class="s1">'databse_config'</span><span class="p">:</span> <span class="n">db_config</span><span class="p">,</span></span></span>
<span class="line" id="e764cb5L10"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L10"></a><span class="line-content"> <span class="c1"># ...</span></span></span>
<span class="line" id="e764cb5L11"><a class="line-number" href="http://publ.beesbuzz.biz/manual/deploying/764-Using-MySQL-MariaDB-as-your-backing-store#e764cb5L11"></a><span class="line-content"><span class="p">}</span></span></span>
</pre></figure><p>but as always it is important to ensure the security of this file; environment-based configuration is traditionally considered to be much easier to secure and prevent mishaps such as accidentally checking it into source control.</p>
]]>
</content>
</entry>
<entry>
<title>Publ v0.7.26 released</title>
<link href="http://publ.beesbuzz.biz/blog/274-Publ-v0-7-26-released" rel="alternate" type="text/html" />
<published>2023-08-21T02:45:00-07:00</published>
<updated>2023-08-21T02:45:00-07:00</updated>
<id>urn:uuid:adaa6960-823e-505d-8783-3d4953e0d95a</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>Here’s some new bugfixes and features!</p>
<ul>
<li>OpenGraph tags now validate per the W3C validator</li>
<li>Images can now take a value of <a href="http://publ.beesbuzz.biz/manual/335-Image-renditions#link">link=True</a> in order to force a link to the full-size rendition <em>without</em> setting a lightbox gallery ID</li>
<li>Links will no longer include the template name if it’s the same as the category default (so you no longer need to do annoying things like <code>view.link(template=template if template.name != 'index')</code></li>
<li>Similarly, path-alias to the <code>index</code> template will now work correctly if the category’s default template is <em>not</em> <code>index</code></li>
</ul>
<p>At some point in the not-too-distant future, two major overhauls are going to need to happen to Publ:</p>
<ol>
<li><p><a href="https://github.com/PlaidWeb/Publ/issues/514">Moving away from Pony ORM</a> to something that works with Python 3.11 (possibly SQL Alchemy or even moving to lower-level indexing)</p><p>I really like Pony ORM, but unfortunately some of the functionality I rely on only works with Python 3.10 and earlier, and a fix doesn’t seem likely to happen any time soon. (I’d love to be proven wrong, of course!)</p></li>
<li><p><a href="https://github.com/PlaidWeb/Publ/issues/261">Finally replacing the Markdown processor</a> with something that’s actively-maintained</p><p>Misaka has been in archive mode for quite some time now, as its underlying Markdown implementation (hoedown) is abandoned. It <em>works</em> but it’s unclear how long it’ll stay working, and I’d rather stay ahead of the game.</p><p>Plus, Misaka complicates the build environment for Publ anyway, since on platforms without a native build in pypi, it has to fetch the sources and compile by itself, and this isn’t very friendly to a lot of deployment environments. Having a pure-Python implementaton would make things a lot nicer.</p><p>A more modern Markdown implementation would also enable a bunch of stuff that doesn’t work quite right as-is, like having inline <code><aside></code> and <code><details></code> within an entry. It’d also be a good excuse to finally add a few features I’ve been wanting to do, such as support for inline/sidebar footnotes and opengraph media embeds.</p><p>This would require a complete rewrite of the Markdown processing within Publ, although those changes would at least be fairly self-contained. Unfortunately, a lot of the existing Markdown-handling code is extremely specific to Misaka’s quirks, so this might be something that takes a lot of iteration to get right. In particular, I worry that some of the Publ syntax extensions (particularly image rendition arguments, code block labeling, and multiple-image sets) might be difficult to support in a different engine with different parsing rules.</p></li>
</ol>
<p>Also, some recent conversations have led me to realize that Publ’s documentation could be a lot better. If you’re interested in helping out, see <a href="https://github.com/PlaidWeb/publ-site/issues/33">publ-site issue #33</a>.</p>
]]>
</content>
</entry>
<entry>
<title>Webmention.js 0.5.5 released - important security update!</title>
<link href="http://publ.beesbuzz.biz/blog/789-Webmention-js-0-5-5-released-important-security-update" rel="alternate" type="text/html" />
<published>2023-07-13T12:14:38-07:00</published>
<updated>2023-07-13T12:14:38-07:00</updated>
<id>urn:uuid:4e3d2e46-476b-5800-a94b-fb74eb3c0947</id>
<author><name>fluffy</name></author>
<content type="html">
<![CDATA[
<p>There is a <a href="https://huntr.dev/bounties/75cfb7ad-a75f-45ff-8688-32a9c55179aa">known XSS exploit</a> in <a href="https://github.com/PlaidWeb/webmention.js">webmention.js</a> 0.5.4 and earlier. If you are running webmention.js on your site, <em>please</em> update to the latest version!</p><p>Many thanks to <a href="https://huntr.dev/users/tyage">@tyage</a> for reporting this vulnerability (and <a href="https://github.com/psmoros">@psmoros</a> for facilitating the report, as well as running <a href="https://huntr.dev/">huntr.dev</a> which looks like a great security research and reporting platform).</p>
]]>
</content>
</entry>
</feed>
If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid Atom 1.0" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src
attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=http%3A//publ.beesbuzz.biz/feed