<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>writefreely &amp;mdash; Third Spruce Tree On The Left</title>
    <link>https://awadwatt.com/tezoatlipoca/tag:writefreely</link>
    <description>No, not that one… up…. right… yes. That one. - Fedi-follow @tezoatlipoca@awadwatt.com</description>
    <pubDate>Sun, 26 Apr 2026 12:42:09 -0400</pubDate>
    <item>
      <title>Customizing the CSS for #WriteFreely is a pain in the butt</title>
      <link>https://awadwatt.com/tezoatlipoca/customizing-the-css-for-writefreely-is-a-pain-in-the-butt</link>
      <description>&lt;![CDATA[  You like the style of my blog? It only took me all afternoon. I may have some work catch-up to do this weekend. &#xA;&#xA;So one of the reasons I broke up with WordPress, other than it was heckaspensive to host a domain, and it was over featured, and I wanted to self-host, etc., etc. - was because I couldn&#39;t futz with the stylesheet for this blog without paying even more money. That&#39;s dumb. &#xA;&#xA;I mean all I wanted was monospaced text for snips of code, is that too much to ask for?&#xA;!--more--&#xA;#WriteFreely on the other hand, lets you muck with your #CSS directly. However, it&#39;s not quite as simple as it would seem. For one, the last time I futzed with Cascading Style Sheets, #webrings were still a thing and everyone still used #ICQ. CSS has come a long way and is a lot more powerful - at the same time a lot more complex.&#xA;&#xA;Out of the box WriteFreely CSS customization&#xA;So drill into your Blog&#39;s customization menu either from your blog&#39;s landing/index page:&#xA;&#xA;or from your account&#39;s Blogs page:&#xA;&#xA;and scroll down until you see Custom CSS. Then, all you have to do is paste in your custom CSS, save and go check it out right?&#xA;&#xA;Not quite. Throw in some basics like an h1 or a a:hover and you&#39;ll find it will work in some instances but not others. &#xA;&#xA;What happens is, the custom CSS you paste in there has to compete with the site/WriteFreely&#39;s default stylesheet. THAT bad boy is linked over here. No, that&#39;s no mistake; and yes, it IS a big glob of CSS with no formatting or whitespace or comments - good luck reading that; that&#39;s the form its served up from WriteFreely&#39;s statics folder. &#xA;&#xA;The reason that&#39;s a big glob is because it&#39;s rendered - during WriteFreely install - on the fly from some LESS scripts; LESS is a CSS pseudo language, and there&#39;s a LESS node.js tool that compiles them into CSS.  So the source of the stylesheets are easier to maintain for the WF/Write.As developers, but makes it a bit thicker for us trying to twiddle with our blog styles. &#xA;&#xA;CSS Specificity Sucks&#xA;&#xA;The problem we bang up against is CSS Specificity - to whit, the more specific, or narrow in scope your style declaration is, the higher precedence it will have. For example, we could use this CSS&#xA;&#xA;h1 {&#xA; color: blue&#xA;}&#xA;but then have the HTML &#xA;h1 style=&#34;color: pink&#34;The heading yo/h1&#xA;and the latter would win (in the CSS engine Battle For Supremacy) because its more specific. &#xA;&#xA;So this is the same WriteFreely default stylesheet from above, but run through the nice CSS Formatter at cleancss.com. Look at all those very specific styles! For example, we could be trying to change the font-size and padding of every h1, but we&#39;d get clobbered by&#xA;&#xA;body#subpage #wrapper h1{&#xA;    font-size:2.5em;&#xA;    letter-spacing:-2px;&#xA;    padding:0 2rem 2rem;&#xA;}&#xA;.. that is any h1 tag in the HTML that is a descendant of a body tag (with an id=subpage) or any element with id=wrapper.&#xA;&#xA;The helpful link - below the box where you paste your CSS - to the CSS customization page over at Write.As gives you a few hints of what you have to cover, but not much. &#xA;&#xA;UGH. HTML. I still have that Dreamweaver 3 CD around somewhere..&#xA;&#xA;What you have to do is delve into the HTML that WF spits out and see what&#39;s there. OR, you can use a tool (like I do) that lets you load the webpage and analyze all the CSS stylings. I use Skybound&#39;s Stylizer for Windows, it lets you click on page elements and see what style rules/declarations from where are affecting it, and you can tweak or suppress any declaration, then copy-paste your new styles into your new stylesheet.&#xA;&#xA;There are two main pages we care about in our WF blog: the blog&#39;s index page - this is the landing page for that blog; and a &#34;post&#34; page for each WF post entry. Diving into the HTML for the index we see:&#xA;&#xA;BODY#collection&#xA; HEADER    &lt;-- pinned posts, the byline from the Customize page&#xA;  H1 blog title - link to this page&#xA;SECTION#wrapper   &lt;-- the list of individual post titles&#xA; ARTICLE     &lt;-- each one is wrapped in one of these&#xA; H2 article title&#xA; TIME post date&#xA; DIV &#xA;  article content&#xA;and on each blog post&#39;s individual page or direct URL&#xA;&#xA;BODY#post&#xA; HEADER&#xA;  H1 link back to index page&#xA; ARTICLE&#xA;so you see, if you tweak the style for an element, say p, it will get clobbered if there is a more specific ruling for the same attributes for a p that shows under a BODY id=post or BODY id=collection tag. &#xA;&#xA;So - either you make overriding style declarations for everything:&#xA;&#xA;body#post,body#collection p {&#xA;    CSS for p&#xA;   }&#xA;but unless you&#39;re a CSS guru (I am NOT), WriteFreely&#39;s paste-your-CSS widget (which has a nice syntax checker) might complain about those tags already being defined which was a real hassle for me. Or you can use the allowed, but probably-not-the-best-way method, the !important directive. &#xA;&#xA;h3 {&#xA;    color: #FFCC00 !important;&#xA;}&#xA;The !important directive tells the CSS engine yeah, I know a more specific style declaration may take precedence, but I really want THIS attribute in this declaration to take priority. &#xA;&#xA;So the !important directive lets us pull a trump card and force our attribute declarations over the ones in the default stylesheet. But what about where we don&#39;t even want an attribute to be specified? Well, the sad news is you have to overwrite each attribute to their &#34;null&#34; or &#34;default&#34; state. For example, the default style for preformatted or pre tags is: &#xA;&#xA;BODY#collection PRE, BODY#post PRE, BODY#subpage PRE&#xA;{&#xA;&#x9;max-width: 100%;&#xA;&#x9;margin: 0;&#xA;&#x9;background: #F8F8F8;&#xA;&#x9;border: 1px solid #CCC;&#xA;&#x9;padding: 0.375em 0.625em;&#xA;&#x9;font-size: 0.86em;&#xA;&#x9;-webkit-border-radius: .25em;&#xA;&#x9;-moz-border-radius: .25em;&#xA;&#x9;border-radius: 0.25em;&#xA;}&#xA;I didn&#39;t wan&#39;t the rounded border, the padding or any of that stuff, but I had to overwrite all the attributes:&#xA;pre {&#xA;    &#xA;    border: 1px solid #FFCC00 !important;&#xA;    padding: 10px !important;&#xA;    line-height: 1 !important;&#xA;    max-width: 100% !important;&#xA;&#x9;margin: 0 !important;&#xA;&#x9;background:#222222 !important;&#xA;&#x9;font-size: smaller !important;&#xA;&#x9;-webkit-border-radius: 0 !important;&#xA;&#x9;-moz-border-radius: 0 !important;&#xA;&#x9;border-radius: 0 !important;&#xA;}&#xA;Not a huge deal; it&#39;s just an annoyance is all. Depending on what type of attribute, the &#34;null&#34; or &#34;default&#34; value could be 0 (for most dimensions, thickness, pixels, %s) &#34;none&#34; or &#34;auto&#34;. &#xA;&#xA;In any case, here&#39;s the final stylesheet for this blog - Not super awesome (and not documented yet) but it covers all of the Markdown styles that WriteFreely supports, that I cover over in my WriteFreely Markdown Cheat Sheet. &#xA;&#xA;If you are a Master In The Way Of Exploding Stylesheet and can point out how I&#39;m pretty stupid and there was a totally easier - or more elegant from a legit CSS cascading sheet way to do this, I would be totally grateful for your wisdom. &#xA;&#xA;References&#xA;[https://guides.write.as/customizing/#custom-css] &lt;- WF customizing guide&#xA;[https://www.w3schools.com/cssref/cssselectors.php] &lt;- CSS selectors: tags, ids, classes, attributes etc. &#xA;[https://www.w3schools.com/css/cssspecificity.asp] &lt;- specificity&#xA;[https://www.cleancss.com/css-beautify/] - Dan&#39;s Tools CSS Formatter &lt;chef&#39;s kiss&#xA;[https://github.com/writefreely/writefreely/tree/develop/less] &lt;- WriteFreely stylesheet LESS source&#xA;Changelog&#xA;2023-06-23 - initial revision&#xA;&#xA;a rel=&#34;me&#34; href=&#34;https://mas.to/@tezoatlipoca&#34;follow -  AT tezoatlipoca AT mas.to, or AT tezoatlipoca AT awadwatt.com to follow this blorg directly on the Fediverse./a]]&gt;</description>
      <content:encoded><![CDATA[<blockquote><p>You like the style of my blog? It only took me all afternoon. I may have some work catch-up to do this weekend.</p></blockquote>

<p>So one of the <a href="https://awadwatt.com/tezoatlipoca/why-i-broke-up-with-wordpress" rel="nofollow">reasons I broke up with WordPress</a>, other than it was heckaspensive to host a domain, and it was over featured, and I wanted to self-host, etc., etc. – was because I couldn&#39;t futz with the stylesheet for this blog without paying even <em>more</em> money. That&#39;s dumb.</p>

<pre><code>I mean all I wanted was monospaced text for snips of code, is that too much to ask for?
</code></pre>



<p><a href="/tezoatlipoca/tag:WriteFreely" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">WriteFreely</span></a> on the other hand, lets you muck with your <a href="/tezoatlipoca/tag:CSS" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">CSS</span></a> directly. However, it&#39;s not quite as simple as it would seem. For one, the last time I futzed with Cascading Style Sheets, <a href="/tezoatlipoca/tag:webrings" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">webrings</span></a> were still a thing and everyone still used <a href="/tezoatlipoca/tag:ICQ" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ICQ</span></a>. CSS has come a long way and is a lot more powerful – at the same time a lot more complex.</p>

<h1 id="out-of-the-box-writefreely-css-customization">Out of the box WriteFreely CSS customization</h1>

<p>So drill into your Blog&#39;s customization menu either from your blog&#39;s landing/index page:
<img src="https://awadwatt.com/tez/css.customize.PNG" alt="">
or from your account&#39;s Blogs page:
<img src="https://awadwatt.com/tez/css.customize2.PNG" alt="">
and scroll down until you see <em>Custom CSS</em>. Then, all you have to do is paste in your custom CSS, save and go check it out right?</p>

<p>Not quite. Throw in some basics like an <code>h1</code> or a <code>a:hover</code> and you&#39;ll find it will work in <em>some</em> instances but not others.</p>

<p>What happens is, the custom CSS you paste in there has to compete with the site/WriteFreely&#39;s default stylesheet. <a href="https://awadwatt.com/tez/awadwatt.com_css_write.css" rel="nofollow"><em>THAT</em> bad boy is linked over here</a>. No, that&#39;s no mistake; and yes, it IS a big glob of CSS with no formatting or whitespace or comments – good luck reading that; that&#39;s the form its served up from WriteFreely&#39;s statics folder.</p>

<p><em>The reason</em> that&#39;s a big glob is because it&#39;s rendered – during WriteFreely install – on the fly <a href="https://github.com/writefreely/writefreely/tree/develop/less" rel="nofollow">from some LESS scripts</a>; LESS is a CSS pseudo language, and there&#39;s a LESS node.js tool that compiles them into CSS.  So the <em>source</em> of the stylesheets are easier to maintain for the WF/Write.As developers, but makes it a bit thicker for us trying to twiddle with our blog styles.</p>

<h1 id="css-specificity-sucks">CSS Specificity Sucks</h1>

<p>The problem we bang up against is <a href="https://www.w3schools.com/css/css_specificity.asp" rel="nofollow">CSS Specificity</a> – to whit, the more <em>specific</em>, or <em>narrow in scope</em> your style declaration is, the higher precedence it will have. For example, we could use this CSS</p>

<pre><code>h1 {
 color: blue
}
</code></pre>

<p>but then have the HTML</p>

<pre><code>&lt;h1 style=&#34;color: pink&#34;&gt;The heading yo&lt;/h1&gt;
</code></pre>

<p>and the latter would win (in the CSS engine Battle For Supremacy) because its <em>more specific</em>.</p>

<p>So <a href="https://awadwatt.com/tez/awadwatt.com_css_write_UNBORK.css" rel="nofollow">this is the same WriteFreely default stylesheet from above, but run through the nice CSS Formatter</a> at <a href="https://www.cleancss.com/css-beautify/" rel="nofollow">cleancss.com</a>. Look at all those very specific styles! For example, we could be trying to change the <code>font-size</code> and padding of every <code>h1</code>, but we&#39;d get clobbered by</p>

<pre><code>body#subpage #wrapper h1{
    font-size:2.5em;
    letter-spacing:-2px;
    padding:0 2rem 2rem;
}
</code></pre>

<p>.. that is any <code>h1</code> tag in the HTML that is a descendant of a body tag (with an <code>id=subpage</code>) or any element with <code>id=wrapper</code>.</p>

<p>The helpful link – below the box where you paste your CSS – to the <a href="https://guides.write.as/customizing/#custom-css" rel="nofollow">CSS customization page over at Write.As</a> gives you a few hints of what you have to cover, but not much.</p>

<h1 id="ugh-html-i-still-have-that-dreamweaver-3-cd-around-somewhere">UGH. HTML. I still have that Dreamweaver 3 CD around somewhere..</h1>

<p>What you have to do is delve into the HTML that WF spits out and see what&#39;s there. OR, you can use a tool (like I do) that lets you load the webpage and analyze all the CSS stylings. I use <a href="http://www.skybound.ca/download/" rel="nofollow">Skybound&#39;s Stylizer for Windows</a>, it lets you click on page elements and see what style rules/declarations from <em>where</em> are affecting it, and you can tweak or suppress any declaration, then copy-paste your new styles into your new stylesheet.</p>

<p>There are two main pages we care about in our WF blog: the blog&#39;s index page – this is the landing page for <em>that</em> blog; and a “post” page for each WF post entry. Diving into the HTML for the index we see:</p>

<pre><code>BODY#collection
 HEADER    &lt;-- pinned posts, the byline from the Customize page
  H1 &lt;blog title - link to this page&gt;
SECTION#wrapper   &lt;-- the list of individual post titles
 ARTICLE     &lt;-- each one is wrapped in one of these
 H2 &lt;article title&gt;
 TIME &lt;post date&gt;
 DIV 
  &lt;article content&gt;
</code></pre>

<p>and on each blog post&#39;s individual page or direct URL</p>

<pre><code>BODY#post
 HEADER
  H1 &lt;link back to index page&gt;
 ARTICLE
</code></pre>

<p>so you see, if you tweak the style for an element, say <code>&lt;p&gt;</code>, it will get clobbered if there is a more specific ruling for the same attributes for a <code>&lt;p&gt;</code> that shows under a <code>&lt;BODY id=post&gt;</code> or <code>&lt;BODY id=collection&gt;</code> tag.</p>

<p>So – either you make overriding style declarations for everything:</p>

<pre><code>body#post,body#collection p {
    &lt;CSS for p&gt;
   }
</code></pre>

<p>but unless you&#39;re a CSS guru (I am NOT), WriteFreely&#39;s paste-your-CSS widget (which has a nice syntax checker) might complain about those tags already being defined which was a real hassle for me. Or you can use the allowed, but probably-not-the-best-way method, the <code>!important</code> directive.</p>

<pre><code>h3 {
    color: #FFCC00 !important;
}
</code></pre>

<p>The <code>!important</code> directive tells the CSS engine <em>yeah, I know a more specific style declaration may take precedence, but I really want THIS attribute in this declaration to take priority</em>.</p>

<p>So the <code>!important</code> directive lets us pull a trump card and force <em>our</em> attribute declarations over the ones in the default stylesheet. But what about where we don&#39;t even <em>want</em> an attribute to be specified? Well, the sad news is you have to overwrite each attribute to their “null” or “default” state. For example, the default style for preformatted or <code>pre</code> tags is:</p>

<pre><code>BODY#collection PRE, BODY#post PRE, BODY#subpage PRE
{
	max-width: 100%;
	margin: 0;
	background: #F8F8F8;
	border: 1px solid #CCC;
	padding: 0.375em 0.625em;
	font-size: 0.86em;
	-webkit-border-radius: .25em;
	-moz-border-radius: .25em;
	border-radius: 0.25em;
}
</code></pre>

<p>I didn&#39;t wan&#39;t the rounded border, the padding or any of that stuff, but I had to overwrite all the attributes:</p>

<pre><code>pre {
    
    border: 1px solid #FFCC00 !important;
    padding: 10px !important;
    line-height: 1 !important;
    max-width: 100% !important;
	margin: 0 !important;
	background:#222222 !important;
	font-size: smaller !important;
	-webkit-border-radius: 0 !important;
	-moz-border-radius: 0 !important;
	border-radius: 0 !important;
}
</code></pre>

<p>Not a huge deal; it&#39;s just an annoyance is all. Depending on what type of attribute, the “null” or “default” value could be 0 (for most dimensions, thickness, pixels, %s) “none” or “auto”.</p>

<p>In any case, <a href="https://awadwatt.com/tez/tezoatlipoca.css" rel="nofollow">here&#39;s the final stylesheet for this blog</a> – Not super awesome (and not documented yet) but it covers all of the Markdown styles that WriteFreely supports, that I cover over in my <a href="https://awadwatt.com/tezoatlipoca/writefreely-writers-guide-cheat-sheet" rel="nofollow">WriteFreely Markdown Cheat Sheet</a>.</p>

<p>If you are a Master In The Way Of Exploding Stylesheet and can point out how I&#39;m pretty stupid and there was a totally easier – or more elegant from a legit CSS cascading sheet way to do this, I would be totally grateful for your wisdom.</p>

<h1 id="references">References</h1>
<ul><li>[<a href="https://guides.write.as/customizing/#custom-css" rel="nofollow">https://guides.write.as/customizing/#custom-css</a>] &lt;– WF customizing guide</li>
<li>[<a href="https://www.w3schools.com/cssref/css_selectors.php" rel="nofollow">https://www.w3schools.com/cssref/css_selectors.php</a>] &lt;– CSS selectors: tags, ids, classes, attributes etc.</li>
<li>[<a href="https://www.w3schools.com/css/css_specificity.asp" rel="nofollow">https://www.w3schools.com/css/css_specificity.asp</a>] &lt;– specificity</li>
<li>[<a href="https://www.cleancss.com/css-beautify/" rel="nofollow">https://www.cleancss.com/css-beautify/</a>] &lt;– Dan&#39;s Tools CSS Formatter </li>
<li>[<a href="https://github.com/writefreely/writefreely/tree/develop/less" rel="nofollow">https://github.com/writefreely/writefreely/tree/develop/less</a>] &lt;– WriteFreely stylesheet LESS source</li>
<li></li></ul>

<h1 id="changelog">Changelog</h1>
<ul><li>2023-06-23 – initial revision</li></ul>

<p><a href="https://mas.to/@tezoatlipoca" rel="nofollow">follow –&gt; AT tezoatlipoca AT mas.to, or AT tezoatlipoca AT awadwatt.com to follow this blorg directly on the Fediverse.</a></p>
]]></content:encoded>
      <guid>https://awadwatt.com/tezoatlipoca/customizing-the-css-for-writefreely-is-a-pain-in-the-butt</guid>
      <pubDate>Fri, 23 Jun 2023 18:37:12 -0400</pubDate>
    </item>
    <item>
      <title>What To Know About WriteFreely: The FAQ</title>
      <link>https://awadwatt.com/tezoatlipoca/what-to-know-about-writefreely-the-faq</link>
      <description>&lt;![CDATA[Its been a week  9 months (10/20) or so since I&#39;ve set up my #WriteFreely instance. &#xA;Here&#39;s how I did it &#xA;&#xA;I quite like it as a blogging platform. I&#39;ve learned a few things along the way and since. &#xA;&#xA;Is it the most fully featured blog platform? Nope, not by a long shot. But depending on your needs it might be sufficient for you.  On the Fediverse of late I&#39;ve noticed an uptick of people asking questions about WriteFreely vs. say, Plume or WordPress+their ActivityPub plugin for federation-capable blogs. &#xA;&#xA;Since there are few free WriteFreely instances with open registrations (as opposed to invite only or restricted) where you can experiment with it, you&#39;re going to want to know more about what you get with WriteFreely... or more importantly, what you don&#39;t get, before you $pony up$ for a paid WriteFreely service, or expend the effort to set yourself up your own instance. So let&#39;s answer a few questions, with a particular comparison with WordPress.&#xA;&#xA;WriteFreely vs....&#xA;What are the other Federated blog platforms?&#xA;&#xA;WriteFreely&#xA;&#xA;Plume - this has some additional features that WriteFreely doesn&#39;t have, but isn&#39;t as actively developed.&#xA;&#xA;Write.As - this is actually a hosted WriteFreely instance by the developers of WriteFreely; they have both paid and fee tier accounts.&#xA;&#xA;WordPress+ActivityPub plugin: WordPress&#39;s parent company just bought the developers of the ActivityPub plugin; but to use plugins you need a paid $WordPress$ ($54/month!!) tier. &#xA;&#xA;Drupal + ActivityPub - Drupal has a module that implements ActivityPub on a Drupal site - no shade on Drupal but while its an excellent and capable content management system for managing all of the resources of a complex website, is serious overkill for a personal blog.&#xA;&#xA;Also, rumour has it that &#xA;&#xA;Medium (who just launched a Mastodon instance for their users) and&#xA;Substack&#xA;are working on ActivityPub integrations&#xA;&#xA;Does WriteFreely have....&#xA;Themes? no. WP lets you choose a theme. But without $plugins$ you can&#39;t customize them. &#xA;Blocks? no. WP edits chunks of text in blocks &lt;- to which you can apply various block styles. No such thing here. &#xA;Reeusable text snips/blocks? aka chunks of reusable content? no&#xA;Text formatting? yes.  Text in WriteFreely is formatted using a subset of Markdown. See my writefreely Writer&#39;s Guide – Cheat Sheet&#xA;HTML? yes, a limited subset. see writefreely Writer&#39;s Guide – Cheat Sheet&#xA;Tables? yes; native tables will allow you to use inline Markdown that WF supports, but customization of those tables will be limited to what you can do with stylesheets; if you want to get fancy (e.g. column or row spanning) you can use HTML tables, but any Markdown within those HTML tables will not render. &#xA;custom CSS? yes, at a blog level. You can define custom styles however and apply them to specific text/Markdown elements by wrapping those in span style=&#34;customstyle&#34;/span tags. &#xA;Advanced page layout? no (except what you can accomplish through CSS, divs and tables)&#xA;&#xA;Media/Images&#xA;link to/display media from another site like Imgur or Pixelfed? yes&#xA;embed media from another site? yes, with stuff like iframes: iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/BTdOHBIppx8&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; allowfullscreen/iframe&#xA;&#xA;Can WriteFreely Store Media/Images/Files?&#xA;if you have access to the WriteFreely instance (server) itself? Yes (see below)&#xA;if you do NOT have admin access to the WF instance: no. &#xA;&#xA;WriteFreely currently does not have any built-in file storage, management or upload capability. It will, however, happily host any file that is stored - or linked to - within its statics folder: this is where images like the site favourite/browser tab icon, user &#34;letter&#34; avatars, default site stylesheets are served from.&#xA;&#xA;All of the images used in this blog are hosted by WriteFreely: I have a link from within the statics folder to a different folder that is a Samba network share accessible to the computers on my home network. It would be trivial to setup any means of remote file upload: FTP, cgi-based HTTP upload; if you have administrative access to the server that hosts WriteFreely. &#xA;&#xA;How does WriteFreely Organize/Index My Content?&#xA;create and save multiple drafts? yes&#xA;unpublish a post back to draft? yes&#xA;categories? no&#xA;labels? no&#xA;hashtags? yes - these are ignored by Federated services, but anything you hashtag in a WriteFreely post becomes a link to a listing of ALL posts that also have that hashtag. So this is similar to labels in WordPress. &#xA;multiple blogs per user? Yes (if configured by the instance admin)&#xA;&#xA;What stats does WriteFreely offer?&#xA;For each blog, you can view&#xA;&#xA;how many followers&#xA;for each blog post, how many views&#xA;&#xA;Thats it. Unlike WordPress, the stats are &#34;lifetime&#34; and there&#39;s no advanced breakdown like where viewers are from or how many views per day/month. Unless you&#39;re the instance admin, in which case you can get this info from the WriteFreely log file.&#xA;&#xA;How does WriteFreely Federate?&#xA;When you post in WriteFreely, the first line of your post becomes the &#34;slug&#34; - the text snip that accompanies your post. The post is just a link back to WriteFreely and a preview generated by whatever is viewing it. Here&#39;s how one of my posts appears in Mastadon:&#xA;Here&#39;s how a WriteFreely post appears in Mastadon&#xA;&#xA;can your blogs be &#34;followed&#34; by other users on the Fediverse? yes&#xA;can Fediverse peeps reply/comment on your blog posts? no&#xA;can you mention a hashtag in your post and have it show up under that hashtag in Federated services? no&#xA;can you @mention users and have your post show up in their inbox? yes, but the text around their @mention appears like a direct message and a link to the blog post may not be included. &#xA;can your blog &#34;manage&#34; follows? i.e. block etc. no&#xA;&#xA;In WordPress+ActivityPub plugin Federated users can respond to blog posts, which appear as comments on the post; subsequent comments and replies thread accordingly. &#xA;&#xA;Can data be Imported/Exported? &#xA;Yes - all of your posts (including Drafts) can be exported as markdown files, bundled in a convenient zip. These can be imported into any other WriteFreely instance. &#xA;&#xA;Can I monetize my WriteFreely blog? &#xA;Supposedly - that&#39;s a feature I haven&#39;t played around with yet as it doesn&#39;t interest me. &#xA;&#xA;How does WriteFreely support multiple users?&#xA;WF instances can be configured as single user (in which case registrations aren&#39;t even applicable) or multi-user. If multi-user, the instance can be configured with open registrations (anyone can sign up), invite-only (where invites can be sent from users or only admins). &#xA;&#xA;What about blog privacy?&#xA;Each blog can be configured to be: &#xA;Unlisted -This blog is visible to anyone with its link.&#xA;Private - Only you may read this blog (while you&#39;re logged in).&#xA;Password-protected: A password is required to read this blog.&#xA;Public - This blog is displayed on the public reader, and is visible to anyone with its link. (the Reader is a meta &#34;aggregate&#34; blog where all blogs on the instance show up in a single feed on the instance home page)&#xA;&#xA;There doesn&#39;t seem to be a lot of WriteFreely instances out there where I can sign up for a free account&#xA;&#xA;WF Instances with open registrations get invaded by bot spam accounts relatively quickly. These drown out the active user accounts on each instance (like in the Reader) and/or cause problems for the instance hosting (hardware usage, bandwidth, denial of service). &#xA;&#xA;WriteFreely is Open-Source - How Actively Is It Maintained?&#xA;WriteFreely is actively-ish maintained. As I write this of 2023-09-27, the latest release (https://github.com/writefreely/writefreely/releases) is 3 months old 0.14. The maintainer of the project, @matt@writing.exchange is one of the founders of Write.As, which is a subscription/paid WriteFreely-based blog hosting service, so #writeas is getting all the attention but new updates are promised soon. I can&#39;t comment on how frequently features/fixes get backported from Write.As to WF, I just got here.&#xA;&#xA;Having said that, poking around the GitHub for WF, there are a lot of comments like &#34;is this actively maintained?&#34; ... so .. ¯\\(ツ)/¯  &#xA;&#xA;It&#39;s fairly good &#34;as is,&#34; and I haven&#39;t encountered any bugs so far, but you should know this going in. In any case, the fear of having your blog &#34;locked in&#34; to an unmaintained platform isn&#39;t a concern with WriteFreely as you can export your posts with a click, and Markdown conversion engines are all over the place. Markdown is a fairly ubiquitous text syntax. &#xA;&#xA;Can I have a trial account on YOUR instance? &#xA;Maybe. DM me at @tezoatlipoca@mas.to after you read the about page.&#xA;&#xA;I would like to set up my own WriteFreely Instance&#xA;Well that&#39;s good cause I just wrote up how to do just that.&#xA;&#xA;Changelog&#xA;2023-02-xx - initial&#xA;2023-09-27 - update to &#34;freshness&#34; as 0.14 just dropped.]]&gt;</description>
      <content:encoded><![CDATA[<p>Its been <del>a week</del>  9 months (10/20) or so since I&#39;ve set up my <a href="/tezoatlipoca/tag:WriteFreely" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">WriteFreely</span></a> instance.
<a href="https://awadwatt.com/tezoatlipoca/federated-blog-writefreely-how-to-self-host-on-a-potato" rel="nofollow">Here&#39;s how I did it</a></p>

<p>I quite like it as a blogging platform. I&#39;ve learned a few things along the way and since.</p>

<p>Is it the most fully featured blog platform? Nope, not by a long shot. But depending on your needs it might be sufficient for <em>you</em>.  On the Fediverse of late I&#39;ve noticed an uptick of people asking questions about WriteFreely vs. say, Plume or WordPress+their ActivityPub plugin for federation-capable blogs.</p>

<p>Since there are few <em>free</em> WriteFreely instances with open registrations (as opposed to invite only or restricted) where you can experiment with it, you&#39;re going to want to know more about what you get with WriteFreely... or more importantly, what you don&#39;t get, before you $pony up$ for a paid WriteFreely service, or expend the effort to set yourself up your own instance. So let&#39;s answer a few questions, with a particular comparison with WordPress.</p>

<h2 id="writefreely-vs">WriteFreely vs....</h2>

<p>What are the other Federated blog platforms?</p>
<ul><li><p>WriteFreely</p></li>

<li><p>Plume – this has some additional features that WriteFreely doesn&#39;t have, but isn&#39;t as actively developed.</p></li>

<li><p>Write.As – this is actually a hosted WriteFreely instance by the developers of WriteFreely; they have both paid and fee tier accounts.</p></li>

<li><p>WordPress+ActivityPub plugin: WordPress&#39;s parent company just bought the developers of the ActivityPub plugin; but to use plugins you need a paid $WordPress$ ($54/month!!) tier.</p></li>

<li><p>Drupal + ActivityPub – Drupal has a module that implements ActivityPub on a Drupal site – no shade on Drupal but while its an excellent and capable content management system for managing all of the resources of a complex website, is serious overkill for a personal blog.</p></li></ul>

<p>Also, rumour has it that</p>
<ul><li>Medium (who just launched a Mastodon instance for their users) and</li>
<li>Substack
are working on ActivityPub integrations</li></ul>

<h2 id="does-writefreely-have">Does WriteFreely have....</h2>
<ul><li>Themes? no. WP lets you choose a theme. But without $plugins$ you can&#39;t customize them.</li>
<li>Blocks? no. WP edits chunks of text in blocks &lt;– to which you can apply various block styles. No such thing here.</li>
<li>Reeusable text snips/blocks? aka chunks of reusable content? no</li>
<li>Text formatting? yes.  Text in WriteFreely is formatted using a subset of Markdown. See my <a href="https://awadwatt.com/tezoatlipoca/writefreely-writers-guide-cheat-sheet" rel="nofollow">writefreely Writer&#39;s Guide – Cheat Sheet</a></li>
<li>HTML? yes, a limited subset. see <a href="https://awadwatt.com/tezoatlipoca/writefreely-writers-guide-cheat-sheet" rel="nofollow">writefreely Writer&#39;s Guide – Cheat Sheet</a></li>
<li>Tables? yes; native tables will allow you to use inline Markdown that WF supports, but customization of those tables will be limited to what you can do with stylesheets; if you want to get fancy (e.g. column or row spanning) you can use HTML tables, but any Markdown within those HTML tables will not render.</li>
<li>custom CSS? yes, at a blog level. You can define custom styles however and apply them to specific text/Markdown elements by wrapping those in <code>&lt;span style=&#34;customstyle&#34;&gt;&lt;/span&gt;</code> tags.</li>
<li>Advanced page layout? no (except what you can accomplish through CSS, divs and tables)</li></ul>

<h2 id="media-images">Media/Images</h2>
<ul><li>link to/display media from another site like Imgur or Pixelfed? yes</li>
<li><em>embed</em> media from another site? yes, with stuff like iframes: <iframe width="560" height="315" src="https://www.youtube.com/embed/BTdOHBIppx8" title="YouTube video player" frameborder="0" allowfullscreen=""></iframe></li></ul>

<h2 id="can-writefreely-store-media-images-files">Can WriteFreely Store Media/Images/Files?</h2>
<ul><li>if you have access to the WriteFreely instance (server) itself? Yes (see below)</li>
<li>if you do NOT have admin access to the WF instance: no.</li></ul>

<p>WriteFreely currently does not have any built-in file storage, management or upload capability. It will, however, happily host any file that is stored – or linked to – within its <em>statics</em> folder: this is where images like the site favourite/browser tab icon, user “letter” avatars, default site stylesheets are served from.</p>

<p>All of the images used in this blog are hosted by WriteFreely: I have a link from within the statics folder to a different folder that is a Samba network share accessible to the computers on my home network. It would be trivial to setup any means of remote file upload: FTP, cgi-based HTTP upload; if you have administrative access to the server that hosts WriteFreely.</p>

<h2 id="how-does-writefreely-organize-index-my-content">How does WriteFreely Organize/Index My Content?</h2>
<ul><li>create and save multiple drafts? yes</li>
<li>unpublish a post back to draft? yes</li>
<li>categories? no</li>
<li>labels? no</li>
<li>hashtags? yes – these are ignored by Federated services, but anything you hashtag in a WriteFreely post becomes a link to a listing of ALL posts that also have that hashtag. So this is similar to labels in WordPress.</li>
<li>multiple blogs per user? Yes (if configured by the instance admin)</li></ul>

<h2 id="what-stats-does-writefreely-offer">What stats does WriteFreely offer?</h2>

<p>For each blog, you can view</p>
<ul><li>how many followers</li>
<li>for each blog post, how many views</li></ul>

<p>Thats it. Unlike WordPress, the stats are “lifetime” and there&#39;s no advanced breakdown like where viewers are from or how many views per day/month. <em>Unless you&#39;re the instance admin, in which case you can get this info from the WriteFreely log file.</em></p>

<h2 id="how-does-writefreely-federate">How does WriteFreely Federate?</h2>

<p>When you post in WriteFreely, the first line of your post becomes the “slug” – the text snip that accompanies your post. The post is just a link back to WriteFreely and a preview generated by whatever is viewing it. Here&#39;s how one of my posts appears in Mastadon:
<img src="/tez/slug.PNG" alt="Here&#39;s how a WriteFreely post appears in Mastadon"></p>
<ul><li>can your blogs be “followed” by other users on the Fediverse? yes</li>
<li>can Fediverse peeps reply/comment on your blog posts? no</li>
<li>can you mention a hashtag in your post and have it show up under that hashtag in Federated services? no</li>
<li>can you @mention users and have your post show up in their inbox? yes, but the text around their @mention appears like a direct message and a link to the blog post may not be included.</li>
<li>can your blog “manage” follows? i.e. block etc. no</li></ul>

<p>In WordPress+ActivityPub plugin Federated users can respond to blog posts, which appear as comments on the post; subsequent comments and replies thread accordingly.</p>

<h2 id="can-data-be-imported-exported">Can data be Imported/Exported?</h2>

<p>Yes – all of your posts (including Drafts) can be exported as markdown files, bundled in a convenient zip. These can be imported into any other WriteFreely instance.</p>

<h2 id="can-i-monetize-my-writefreely-blog">Can I monetize my WriteFreely blog?</h2>

<p>Supposedly – that&#39;s a feature I haven&#39;t played around with yet as it doesn&#39;t interest me.</p>

<h2 id="how-does-writefreely-support-multiple-users">How does WriteFreely support multiple users?</h2>

<p>WF instances can be configured as single user (in which case registrations aren&#39;t even applicable) or multi-user. If multi-user, the instance can be configured with open registrations (anyone can sign up), invite-only (where invites can be sent from users or only admins).</p>

<h2 id="what-about-blog-privacy">What about blog privacy?</h2>

<p>Each blog can be configured to be:
Unlisted -This blog is visible to anyone with its link.
Private – Only you may read this blog (while you&#39;re logged in).
Password-protected: A password is required to read this blog.
Public – This blog is displayed on the public reader, and is visible to anyone with its link. (the Reader is a meta “aggregate” blog where all blogs on the instance show up in a single feed on the instance home page)</p>

<h2 id="there-doesn-t-seem-to-be-a-lot-of-writefreely-instances-out-there-where-i-can-sign-up-for-a-free-account">There doesn&#39;t seem to be a lot of WriteFreely instances out there where I can sign up for a free account</h2>

<p>WF Instances with open registrations get invaded by bot spam accounts relatively quickly. These drown out the active user accounts on each instance (like in the Reader) and/or cause problems for the instance hosting (hardware usage, bandwidth, denial of service).</p>

<h2 id="writefreely-is-open-source-how-actively-is-it-maintained">WriteFreely is Open-Source – How Actively Is It Maintained?</h2>

<p>WriteFreely is <em>actively-ish</em> maintained. As <del>I write this</del> of 2023-09-27, the latest release (<a href="https://github.com/writefreely/writefreely/releases" rel="nofollow">https://github.com/writefreely/writefreely/releases</a>) is <del>3 months old</del> 0.14. The maintainer of the project, <a href="https://awadwatt.com/@/matt@writing.exchange" class="u-url mention" rel="nofollow">@<span>matt@writing.exchange</span></a> is one of the founders of Write.As, which is a subscription/paid WriteFreely-based blog hosting service, so <a href="/tezoatlipoca/tag:writeas" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">writeas</span></a> is getting all the attention <strong>but new updates are promised soon</strong>. <del>I can&#39;t comment on how frequently features/fixes get backported from Write.As to WF, I just got here.</del></p>

<p>~~Having said that, poking around the GitHub for WF, there are a lot of comments like “is this actively maintained?” ... so .. ¯\<em>(ツ)</em>/¯  ~~</p>

<p>It&#39;s fairly good “as is,” and I haven&#39;t encountered any bugs so far, but you should know this going in. In any case, the fear of having your blog “locked in” to an unmaintained platform isn&#39;t a concern with WriteFreely as you can export your posts with a click, and Markdown conversion engines are all over the place. Markdown is a fairly ubiquitous text syntax.</p>

<h2 id="can-i-have-a-trial-account-on-your-instance">Can I have a trial account on YOUR instance?</h2>

<p>Maybe. DM me at <a href="https://awadwatt.com/@/tezoatlipoca@mas.to" class="u-url mention" rel="nofollow">@<span>tezoatlipoca@mas.to</span></a> after you read the <a href="https://awadwatt.com/about" rel="nofollow">about page</a>.</p>

<h2 id="i-would-like-to-set-up-my-own-writefreely-instance">I would like to set up my own WriteFreely Instance</h2>

<p><a href="https://awadwatt.com/tezoatlipoca/federated-blog-writefreely-how-to-self-host-on-a-potato" rel="nofollow">Well that&#39;s good cause I just wrote up how to do just that.</a></p>

<h1 id="changelog">Changelog</h1>

<p>2023-02-xx – initial
2023-09-27 – update to “freshness” as 0.14 just dropped.</p>
]]></content:encoded>
      <guid>https://awadwatt.com/tezoatlipoca/what-to-know-about-writefreely-the-faq</guid>
      <pubDate>Thu, 16 Mar 2023 14:22:41 -0400</pubDate>
    </item>
    <item>
      <title>Federated Blog: WriteFreely - How To Self-Host On A Potato</title>
      <link>https://awadwatt.com/tezoatlipoca/federated-blog-writefreely-how-to-self-host-on-a-potato</link>
      <description>&lt;![CDATA[From the CAN YOU BELEIVE, THIS IS RUN ON A SPEAK AND SPELL POWERED BY TWO HAMSTERS ON A WHEEL? Dept.&#xA;&#xA;span style=&#34;backgrounder&#34;#WordPress is nice and all, but it would be nice to have a blog that was ActivityPub friendly, and would fit in with #Mastodon, #Pixelfed, #Friendica and the rest of the #Fediverse. #WriteFreely is one. Here&#39;s how to set yourself up a #WriteFreely instance. /a&#xA;&#xA;I originally was going to write this as a comparison between all the Fediverated or ActivityPub capable blogging platforms out there. But when I got into it, I realized that there are really only a few viable options,  as per the Awesome Mastodon Big List of Everything Fediverse:Blogging (which is an exhaustive and actively maintained resource by the way check it out.). &#xA;&#xA;I think when I migrated to Mastadon from #Birdsite in November, I thought there were way more federated blog platforms, but I&#39;ve since discovered that some Mastadon instances and other microblogging services like #Calkey and #misskey have higher character caps than Mastadon by default - and that&#39;s what I was seeing. &#xA;&#xA;So really WriteFreely was it, and I just dug right into setting it up. &#xA;&#xA;Why are you ditching WordPress?&#xA;We broke up. They were a high maintenance partner and I couldn&#39;t even touch the stylesheet&#xA;&#xA;Why WriteFreely vs. the others? What other options are there? What do I need to know about it?&#xA;I wrote an FAQ - everything you need to know about WriteFreely.&#xA;&#xA;Setting Up WriteFreely&#xA;&#xA;I&#39;m not going to regurgitate the Getting Started/Installation guide as it&#39;s already pretty good. I will however call attention to a few snags I ran into and a few bonus tips I discovered through experimentation. &#xA;&#xA;WriteFreely is written in Go, for which there are cross-platform compilers. At the moment, the project only builds 64-bit linux binaries due to a tool issue (see the change notes), but if you&#39;re not afraid to compile from source you could set this up on a Windows PC if you wanted to. &#xA;&#xA;Platform Choice - OpenSUSE linux&#xA;&#xA;So for now lets go Linux. My &#34;server&#34; is an old gaming PC I&#39;ve been using to run my TV for the last decade, with a stack of spare 60 and 80 GB drives shoved in. I choose OpenSUSE Tumbleweed after some research as&#xA;&#xA;SUSE isn&#39;t a &#34;desktop&#34; distro; it has a KDE desktop sure, but its intended for server operation not end user applications&#xA;it has (Tumbleweed anyway) a continuously updated patch engine like Windows Update; I don&#39;t have to worry about keeping it up to date, I just have to schedule the automatic updates. &#xA;its administration console, Yast, has both a graphical KDE interface, but it also runs from a CLI. Since Im shoving this in a corner of my basement without a monitor, the ability to administer it remotely is key. &#xA;&#xA;Steps followed:&#xA;&#xA;download the network or offline x8664: https://get.opensuse.org/tumbleweed/&#xA;use the image to make a bootable USB key: https://en.opensuse.org/SDB:LiveUSBstick&#xA;boot the PC from the USB key; install OpenSUSE&#xA;&#xA;From here it was following the setup wizard really. When asked, I chose &#34;Desktop with KDE Plasma&#34; so I&#39;d have a nice desktop environment for configuration. &#xA;&#xA;After installation, I:&#xA;&#xA;disabled the &#34;Network Manager&#34; KDE utility so I could control the network interface manually so I could..&#xA;configured the firewall setup/zone and bind it to the network interface: we need to open ports 80 (HTTP), 443 (HTTPs) and allow the ssh service for remote administration. &#xA;configured Network Services   Hostnames&#xA;enabled Samba Server so I could host a network share for static files I want to use in my blog posts (images, files) like \\servername\img\blogname\ - WriteFreely doesn&#39;t have an image/static file &#34;upload&#34; feature yet.  &#xA;I used the Yast and zypper package managers to download and install MySQL (mariadb)&#xA; you&#39;ll be prompted to create one or more &#34;users&#34; for the database. If you create a user for WriteFreely at this point make sure you write down the user name and its password. The username WriteFreely uses doesn&#39;t have to be &#34;writefreely&#34;, it can be &#34;the database user&#34;. I used &#34;mysql&#34;. &#xA;used the MySQL command line tools to make sure the database timezone was UTC. &#xA;&#xA;Download and install WriteFreely&#xA;&#xA;Following the instructions here: https://writefreely.org/start&#xA;When yo get to the writefreely config start stage, this invokes a setup wizard. Most of the questions are straight forward and/or the parameters are described in more detail here: https://writefreely.org/docs/latest/admin/config. I would recommend reading through that list before you run the wizard, although you can always go back and do it again, or just modify the config.ini file it generates and restart writefreely. &#xA;&#xA;You can configure WF to run Secure or Insecure. If secure, it will require a security certificate for HTTPs and host your blogs on port 443. Any request to HTTP on port 80 is redirected. &#xA;&#xA;Eventually the wizard will ask you for site name (awadwatt.com in my case) and a hostname - this should match the fully qualified domain name of this WriteFreely host (e.g. https://awadwatt.com) - if you setup as writefreely.urdomain.org, be sure to include this. This host name is used to generate the crypto keys and it has to match how this host is visible to the internet, otherwise visitors will get HTTPS/TLS handshake errors when trying to view your blog: the hostname WriteFreely is responding from doesn&#39;t match the hostname in the security certificate its presenting to browsers: viewing browsers will go nope! and no one can read your blog.&#xA;&#xA;When asked for database parameters, make sure to use the user name and pwd you wrote down for the database when you configured users in MySql earlier. &#xA;&#xA;The bit about writefreely keys generate: this command has WF reach out to a free service at https://letsencrypt.org/ to generate its HTTPs certificate. What isn&#39;t mentioned is how Let&#39;s Encrypt will block/ignore your host making certificate requests if you do more than 5 requests in the space of an hour. Like, if you flail around trying to get a dynamic DNS working. So, what I&#39;d recommend is running WriteFreely unsecured until you&#39;re ready to get things hooked up on the internet. &#xA;&#xA;Don&#39;t run keys generate until you have a domain mapping setup! - jump ahead to the Dynamic DNS mapping section. &#xA;&#xA;Troubleshooting&#xA;&#xA;So at this point, you&#39;ve configured WriteFreely and if you  start it from the command line writefreely, you&#39;ll see a message about how its serving on port 80/443. If you point a web-browser on your home network to your server&#39;s hostname:&#xA;&#xA;you&#39;ll see your WriteFreely instance hosted OR&#xA;you&#39;ll get a website didn&#39;t respond msg. &#xA;&#xA;If the latter, check:&#xA;firewall issues; WriteFreely doesn&#39;t register as a linux network service (by default) so it doesn&#39;t show up in most linux firewall managers (like Yast); all you can do is open the ports 80 and/or 443. &#xA;if you want to see if WriteFreely is alive and responding, try from the WF host itself:&#xA; curl -v HTTP://localhost - curl is a command line HTTP/s request tool; connecting to localhost sidesteps all firewalls; you should see WriteFreely respond and the curl request show up in the logs WriteFreely is dumping to the command line. &#xA; curl -v HTTP://IP address of WF on your network -try the same thing but using the IP address of your server. &#xA; curl -v HTTP://hostname of wf on your network - this will depend on the ability of your servers hostname to be able to resolve&#xA;if the first one works but the latter two don&#39;t you have firewall issues or DNS resolution issues. &#xA;&#xA;Once you sort these things out, using curl or a web-browser from another computer on your network you&#39;ll see the default WriteFreely page, and in the console where you started WF you&#39;ll see the requests from that remote computer appear. &#xA;&#xA;Post installation Setup&#xA;&#xA;We can run WriteFreely but we want to setup things so WriteFreely starts as a system service so if we have to reboot or whatever we don&#39;t have to remember to restart WriteFreely. &#xA;&#xA;Steps taken: (I installed writefreely in /usr/local/bin/writefreely)&#xA;I moved my config.ini to outside the WF folder so if I update later I don&#39;t destroy my config.ini with a default. Tell WF to use it in another location by stating writefreely -c path/config.ini&#xA;wrote a script to launch WF and dump its standard out and any errors to a file. /usr/local/bin/runwf:&#xA;!/bin/bash&#xA;/usr/local/bin/writefreely/writefreely -c /usr/local/bin/config.ini   /var/log/writefreely.log 2  &amp;1&#xA;&#xA;set WriteFreely up as a systemd service so it can be run by the system and various admin tools. Following https://doc.opensuse.org/documentation/leap/reference/html/book-reference/cha-systemd.html&#xA; created /etc/systemd/system/writefreely.service:&#xA;&#xA;[Unit]&#xA;Description=writefreely systemd service unit file.&#xA;Requires=mariadb.service&#xA;After=mariadb.service&#xA;[Service]&#xA;ExecStart=/bin/bash /usr/local/bin/runwf&#xA;Restart=always&#xA;RestartSec=5&#xA;[Install]&#xA;WantedBy=multi-user.target&#xA;&#xA; the Requires/After tells systems that WriteFreely should wait until after MySql starts before starting.&#xA; ExecStart invokes the script above&#xA; Restart* attepts to restart WF every 5 seconds if it stops running for whatever reason&#xA;&#xA;Great! Now WriteFreely starts with our system and can be started/stopped with our admin tools (Yast) or from the command line with systemctl start/stop/restart writefreely&#xA;&#xA;Post post setup Config&#xA;Now we have our WF instance running, we want to forward some ports through our home wifi router, host some images and map our domain to it points itself at our home&#39;s external IP address. &#xA;&#xA;Setup WriteFreely to Host Images&#xA;I thought about throwing up a Pixelfed instance on this box - I have the disk space and the database. But I&#39;d have to futz around with the conflicting port addresses and mapping/forwarding through my firewall, or get into subdomain mapping like pixelfed.awadwatt.com etc. &#xA;&#xA;I toyed around with setting up an Apache virtual host at awadwatt.com/img/ on a random port (remember WF already gloms 80 and 443) and was able to get that to work, but as I found out, linking to unsecure http images from within a WriteFreely page hosted in secure https throws browsers for a loop; I&#39;d have to run WF unsecure at port 80 for that to work or figure out how to get that virtual host, at a custom port (6900) to host https. Getting an Apache virtual host to do Secure HTTP NOT on port 443 was beyond my skills, or rather my patience. And having to type image URLs as https://awadwatt.com:6900/img/file.png got to be real tedious real fast.&#xA;&#xA;Then I realized: WriteFreely already hosts images (or static files anyway)! The little draft icon this, the avatar icons, the (default) CSS stylesheets, the browser tab &#34;favicon.ico&#34; file etc. &#xA;Sure enough, poking around in /usr/local/bin/writefreely there&#39;s a statics folder, and everything in there is addressable from the domain root. So we could just toss our images in the statics folder, but we can do better than that; for one, I didn&#39;t want my images folder trashed whenever I upgraded the application. &#xA;&#xA;So I linked a user specific sub-folder from the static folder to where the images live and made sure the user that WriteFreely runs as can traverse it. Remember that samba folder I created earlier? yep: &#xA;&#xA;tezoatlipoca@famine:/usr/local/bin/writefreely/static  ls -lat&#xA;total 16&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca  118 Mar  9 14:32 .&#xA;-rwxrwxrwx 1 root         root           53 Mar  9 14:29 google296e6456a3479f2c.html&#xA;lrwxrwxrwx 1 root         root           23 Mar  6 22:00 tez -  /diskb/img/tezoatlipoca&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca   90 Mar  6 10:54 ..&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca   98 Nov 11 02:51 css&#xA;-rw-rw-r-- 1 tezoatlipoca tezoatlipoca 6090 Nov 11 02:51 favicon.ico&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca 1218 Nov 11 02:51 fonts&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca  852 Nov 11 02:51 img&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca  390 Nov 11 02:51 js&#xA;drwxrwxr-x 1 tezoatlipoca tezoatlipoca   20 Nov 11 02:51 local&#xA;&#xA;So now (at least on my home network), all I have to do is save an image to \\famine\img\tezoatlipoca and it shows up at http://awadwatt.com/tez/&#xA;&#xA; Dunno how robust WF&#39;s static hosting will hold up under punishment, but I&#39;ve had a few img bearing posts get hit by a few hundred Mastodon instances and so far so good.&#xA;&#xA;At some point Ill go back to that Apache virtual host method, I really want to get a CGI file uploading script working so I can upload images from work (without opening an ssh hole in my home router for sftp)&#xA;&#xA;Port Forwarding&#xA;&#xA;Not too much to say here other than log into your home wifi/internet router and forward ports 80 (http) and 443 (https) to your WriteFreely instance host. &#xA;&#xA;To diagnose that your host is reachable, use a service like https://whatismyipaddress.com/ to determine your wifi router&#39;s external IP address. Then, use your cell phone (disable the wifi!) or from work/school/somewhere not at home, try and connect to that IP address. If you see your WriteFreely instance, huzzah!&#xA;&#xA;If not, check to see if those ports are open/being forwarded properly by probing those ports at that external IP address. The Shields Up! tool by Gibson Research   Scan &#34;All system ports&#34; has been around forever and its still good. The only ports you should see in red are 80 and 443: &#xA;Shields Up map: only 80 and 443 are forwarded and responding == red&#xA; &#xA;span id=&#34;dns&#34;Domain Mapping - Dynamic DNS/span&#xA;&#xA;Our last step is to set up DNS mapping to our external IP. You could call it quits here, I suppose, and just say, &#34;hey, my blog is at external IP,&#34; but any Federated service that picks up your blog posts will always expect to find it at the same domain location. Home IP addresses on fixed cable/fibre connections tend not to change too much, but you can never be sure that your IP won&#39;t change. Having a static DNS domain-  IP address mapping solves that problem. &#xA;&#xA;If our instance was hosted by, or colocated IN an ISP&#39;s data center, then yes, part of that hosting arrangement would be allocation of a fixed IP address.  &#xA;&#xA;Fortunately, there are (paid, cheap or free) Dynamic DNS services. Essentially these work in two steps: &#xA;&#xA;YOU modify your (or some) domain registration (GoDaddy.com, Network Solutions, wherever you registered it) so that its DNS servers of record (i.e. the ones who own the mapping) are the Dynamic DNS services&#39; servers. &#xA; now, when a computer wants to find yourdomain.org, it asks ITS upstream DNS server (wifi router, ISP etc.); the upstream DNS server know to ask Dynamic DNS&#39;s DNS server; it will know. How? &#xA;YOU tell Dynamic DNS&#39;s servers what IP address to map yourdomain.org TO. &#xA; you can do this manually, or you can set up some automated job/process that runs periodically to update/confirm your server&#39;s IP address.&#xA;&#xA;How you set this up will depend on the specific Dynamic DNS provider. &#xA;&#xA;I used https://freedns.afraid.org/ which has both free and paid tiers of dynamic DNS mapping. At my domain registrar, I changed my domain registration&#39;s DNS servers:&#xA;&#xA;Domain Name: AWADWATT.COM&#xA;Registrar WHOIS Server: whois.networksolutions.com&#xA;Registrar URL: http://networksolutions.com&#xA;Creation Date: 1999-08-25T21:28:32Z&#xA;snip&#xA;Name Server: NS1.AFRAID.ORG&#xA;Name Server: NS2.AFRAID.ORG&#xA;Name Server: NS3.AFRAID.ORG&#xA;Name Server: NS4.AFRAID.ORG&#xA;to theirs. &#xA;&#xA;Then, an hourly cron (scheduled system task) job runs to update the afraid.org name servers with my external IP address. Easy!&#xA;&#xA;Just remember the SSL keys that writefreely keys generate depend on the domain address your instance is found at. So once you get your domain mapping up, be sure to go back and create secure https keys otherwise visiting clients/federated services will get TLS and SSL errors - the host/domain in the keys doesn&#39;t match how your server appears on the internet. &#xA;&#xA;Also: DNS propagation can take some time: several days. So don&#39;t be surprised after changing your domain   DNS servers and setting up dynamic DNS mapping, it could take several hours to several days before your WriteFreely instance consistently is available at yourdomain.org. &#xA;&#xA;Done! Whats left? Feedback&#xA;&#xA;That wasn&#39;t so bad? Figuring this out and flexing some long dormant linux skills took me maybe 6? 8? hours over a weekend. Im sure I could do this in just a few hours. I&#39;d still like to:&#xA;&#xA;try and get WriteFreely running on Windows; there are some older Windows binaries available in various repositories, but supposedly its possible to compile from source. But getting a current Windows binary (or a MacOS one!) makes self-hosting available to so many more people. &#xA;figure out an image uploading mechanism to complement my static subfolder link hack. For one, if I have guest accounts on my WF instance I&#39;d like to be able to offer them image hosting capabilities, without having to log into my home wifi to do it. &#xA;in-post table of contents using headers! - sometime in the last week or so I saw a post from a Write.As user who figured out a way - using only CSS - to dynamically generate a table of contents of all the headers in your post; gotta dig that up. &#xA;experiment with CSS for customization_ - DONE&#xA;Put behind NGINX&#xA;&#xA;Did you follow this? Did It work? Problems? &#xA;Seriously, I&#39;d love to hear from you. tezoatlipoca @ gmail.com or @tezoatlipoca @ mas.to. &#xA;&#xA;Changelog&#xA;2023-03-07  - initial&#xA;2024-10-15 - CSS and NGINX links.&#xA;  &#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>From the CAN YOU BELEIVE, THIS IS RUN ON A SPEAK AND SPELL POWERED BY TWO HAMSTERS ON A WHEEL? Dept.</p>

<p><span style="backgrounder"><a href="/tezoatlipoca/tag:WordPress" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">WordPress</span></a> is nice and all, but it would be nice to have a blog that was ActivityPub friendly, and would fit in with <a href="/tezoatlipoca/tag:Mastodon" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Mastodon</span></a>, <a href="/tezoatlipoca/tag:Pixelfed" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Pixelfed</span></a>, <a href="/tezoatlipoca/tag:Friendica" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Friendica</span></a> and the rest of the <a href="/tezoatlipoca/tag:Fediverse" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Fediverse</span></a>. <a href="/tezoatlipoca/tag:WriteFreely" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">WriteFreely</span></a> is one. Here&#39;s how to set yourself up a <a href="/tezoatlipoca/tag:WriteFreely" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">WriteFreely</span></a> instance. </a></p>

<p>I originally was going to write this as a comparison between all the Fediverated or ActivityPub capable blogging platforms out there. But when I got into it, I realized that there are really only a few viable options,  as per the <a href="https://hueyy.github.io/awesome-mastodon/#blogging" rel="nofollow">Awesome Mastodon Big List of Everything Fediverse:Blogging</a> (which is an exhaustive and actively maintained resource by the way check it out.).</p>

<p>I think when I migrated to Mastadon from <a href="/tezoatlipoca/tag:Birdsite" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Birdsite</span></a> in November, I thought there were way more federated blog platforms, but I&#39;ve since discovered that some Mastadon instances and other microblogging services like <a href="/tezoatlipoca/tag:Calkey" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Calkey</span></a> and <a href="/tezoatlipoca/tag:misskey" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">misskey</span></a> have higher character caps than Mastadon by default – and that&#39;s what I was seeing.</p>

<p>So really WriteFreely was it, and I just dug right into setting it up.</p>

<p><strong>Why are you ditching WordPress?</strong>
<a href="https://awadwatt.com/tezoatlipoca/why-i-broke-up-with-wordpress" rel="nofollow">We broke up. They were a high maintenance partner and I couldn&#39;t even touch the stylesheet</a></p>

<p><strong>Why WriteFreely vs. ? What other options are there? What do I need to know about it?</strong>
<a href="https://awadwatt.com/tezoatlipoca/what-to-know-about-writefreely-the-faq" rel="nofollow">I wrote an FAQ – everything you need to know about WriteFreely.</a></p>

<h1 id="setting-up-writefreely">Setting Up WriteFreely</h1>

<p>I&#39;m not going to regurgitate the <a href="https://writefreely.org/start" rel="nofollow">Getting Started/Installation guide</a> as it&#39;s already pretty good. I will however call attention to a few snags I ran into and a few bonus tips I discovered through experimentation.</p>

<p>WriteFreely is written in Go, for which there are cross-platform compilers. At the moment, the project only builds 64-bit linux binaries due to a tool issue (<a href="https://github.com/writefreely/writefreely/releases" rel="nofollow">see the change notes</a>), but if you&#39;re not afraid to compile from source you could set this up on a Windows PC if you wanted to.</p>

<h2 id="platform-choice-opensuse-linux">Platform Choice – OpenSUSE linux</h2>

<p>So for now lets go Linux. My “server” is an old gaming PC I&#39;ve been using to run my TV for the last decade, with a stack of spare 60 and 80 GB drives shoved in. I choose OpenSUSE Tumbleweed after some research as</p>
<ul><li>SUSE isn&#39;t a “desktop” distro; it has a KDE desktop sure, but its intended for server operation not end user applications</li>
<li>it has (Tumbleweed anyway) a continuously updated patch engine like Windows Update; I don&#39;t have to worry about keeping it up to date, I just have to schedule the automatic updates.</li>
<li>its administration console, Yast, has both a graphical KDE interface, but it also runs from a CLI. Since Im shoving this in a corner of my basement without a monitor, the ability to administer it remotely is key.</li></ul>

<p>Steps followed:</p>
<ul><li>download the network or offline x86_64: <a href="https://get.opensuse.org/tumbleweed/" rel="nofollow">https://get.opensuse.org/tumbleweed/</a></li>
<li>use the image to make a bootable USB key: <a href="https://en.opensuse.org/SDB:Live_USB_stick" rel="nofollow">https://en.opensuse.org/SDB:Live_USB_stick</a></li>
<li>boot the PC from the USB key; install OpenSUSE</li></ul>

<p>From here it was following the setup wizard really. When asked, I chose “Desktop with KDE Plasma” so I&#39;d have a nice desktop environment for configuration.</p>

<p>After installation, I:</p>
<ul><li>disabled the “Network Manager” KDE utility so I could control the network interface manually so I could..</li>
<li>configured the firewall setup/zone and bind it to the network interface: we need to open ports 80 (HTTP), 443 (HTTPs) and allow the ssh service for remote administration.</li>
<li>configured Network Services &gt; Hostnames</li>
<li>enabled Samba Server so I could host a network share for static files I want to use in my blog posts (images, files) like <code>\\servername\img\blogname\</code> – WriteFreely doesn&#39;t have an image/static file “upload” feature yet.<br></li>
<li>I used the Yast and zypper package managers to download and install MySQL (mariadb)
<ul><li>you&#39;ll be prompted to create one or more “users” for the database. If you create a user for WriteFreely at this point make sure you write down the user name and its password. The username WriteFreely uses doesn&#39;t have to be “writefreely”, it can be “the database user”. I used “mysql”.</li></ul></li>
<li>used the MySQL command line tools to make sure the database timezone was UTC.</li></ul>

<h2 id="download-and-install-writefreely">Download and install WriteFreely</h2>

<p>Following the instructions here: <a href="https://writefreely.org/start" rel="nofollow">https://writefreely.org/start</a>
When yo get to the <code>writefreely config start</code> stage, this invokes a setup wizard. Most of the questions are straight forward and/or the parameters are described in more detail here: <a href="https://writefreely.org/docs/latest/admin/config" rel="nofollow">https://writefreely.org/docs/latest/admin/config</a>. I would recommend reading through that list before you run the wizard, although you can always go back and do it again, or just modify the <code>config.ini</code> file it generates and restart writefreely.</p>

<p>You can configure WF to run Secure or Insecure. If secure, it will require a security certificate for HTTPs and host your blogs on port 443. Any request to HTTP on port 80 is redirected.</p>

<p>Eventually the wizard will ask you for site name (awadwatt.com in my case) and a hostname – this should match the fully qualified domain name of this WriteFreely host (e.g. <a href="https://awadwatt.com" rel="nofollow">https://awadwatt.com</a>) – if you setup as writefreely.urdomain.org, be sure to include this. <strong>This host name</strong> is used to generate the crypto keys and it has to match how this host is visible to the internet, otherwise visitors will get HTTPS/TLS handshake errors when trying to view your blog: the hostname WriteFreely is responding from doesn&#39;t match the hostname in the security certificate its presenting to browsers: viewing browsers will go <em>nope!</em> and no one can read your blog.</p>

<p>When asked for database parameters, make sure to use the user name and pwd you wrote down for the database when you configured users in MySql earlier.</p>

<p>The bit about <code>writefreely keys generate</code>: this command has WF reach out to a free service at <a href="https://letsencrypt.org/" rel="nofollow">https://letsencrypt.org/</a> to generate its HTTPs certificate. What isn&#39;t mentioned is how Let&#39;s Encrypt will block/ignore your host making certificate requests if you do more than 5 requests in the space of an hour. Like, if you flail around trying to get a dynamic DNS working. So, what I&#39;d recommend is running WriteFreely unsecured until you&#39;re ready to get things hooked up on the internet.</p>

<p><strong>Don&#39;t run <code>keys generate</code> until you have a domain mapping setup!</strong> – jump ahead to the <a href="#dns" rel="nofollow">Dynamic DNS mapping section</a>.</p>

<h2 id="troubleshooting">Troubleshooting</h2>

<p>So at this point, you&#39;ve configured WriteFreely and if you  start it from the command line <code>writefreely</code>, you&#39;ll see a message about how its serving on port 80/443. If you point a web-browser on your home network to your server&#39;s hostname:</p>
<ul><li>you&#39;ll see your WriteFreely instance hosted OR</li>
<li>you&#39;ll get a website didn&#39;t respond msg.</li></ul>

<p>If the latter, check:
* firewall issues; WriteFreely doesn&#39;t register as a linux network service (by default) so it doesn&#39;t show up in most linux firewall managers (like Yast); all you can do is open the ports 80 and/or 443.
* if you want to see if WriteFreely is alive and responding, try from the WF host itself:
 * <code>curl -v HTTP://localhost</code> – curl is a command line HTTP/s request tool; connecting to localhost sidesteps all firewalls; you should see WriteFreely respond and the curl request show up in the logs WriteFreely is dumping to the command line.
 * <code>curl -v HTTP://&lt;IP address of WF on your network&gt;</code> -try the same thing but using the IP address of your server.
 * <code>curl -v HTTP://&lt;hostname of wf on your network&gt;</code> – this will depend on the ability of your servers hostname to be able to resolve
* if the first one works but the latter two don&#39;t you have firewall issues or DNS resolution issues.</p>

<p>Once you sort these things out, using curl or a web-browser from another computer on your network you&#39;ll see the default WriteFreely page, and in the console where you started WF you&#39;ll see the requests from that remote computer appear.</p>

<h1 id="post-installation-setup">Post installation Setup</h1>

<p>We can run WriteFreely but we want to setup things so WriteFreely starts as a system service so if we have to reboot or whatever we don&#39;t have to remember to restart WriteFreely.</p>

<p>Steps taken: (I installed writefreely in <code>/usr/local/bin/writefreely</code>)
* I moved my <code>config.ini</code> to outside the WF folder so if I update later I don&#39;t destroy my config.ini with a default. Tell WF to use it in another location by stating <code>writefreely -c &lt;path/config.ini&gt;</code>
* wrote a script to launch WF and dump its standard out and any errors to a file. <code>/usr/local/bin/run_wf</code>:</p>

<pre><code>#!/bin/bash
/usr/local/bin/writefreely/writefreely -c /usr/local/bin/config.ini &gt; /var/log/writefreely.log 2&gt;&amp;1
</code></pre>
<ul><li>set WriteFreely up as a <code>systemd</code> service so it can be run by the system and various admin tools. Following <a href="https://doc.opensuse.org/documentation/leap/reference/html/book-reference/cha-systemd.html" rel="nofollow">https://doc.opensuse.org/documentation/leap/reference/html/book-reference/cha-systemd.html</a>
<ul><li>created <code>/etc/systemd/system/writefreely.service</code>:</li></ul></li></ul>

<pre><code>[Unit]
Description=writefreely systemd service unit file.
Requires=mariadb.service
After=mariadb.service
[Service]
ExecStart=/bin/bash /usr/local/bin/run_wf
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
</code></pre>
<ul><li>the Requires/After tells systems that WriteFreely should wait until after MySql starts before starting.</li>
<li>ExecStart invokes the script above</li>
<li>Restart* attepts to restart WF every 5 seconds if it stops running for whatever reason</li></ul>

<p>Great! Now WriteFreely starts with our system and can be started/stopped with our admin tools (Yast) or from the command line with <code>systemctl start/stop/restart writefreely</code></p>

<h1 id="post-post-setup-config">Post post setup Config</h1>

<p>Now we have our WF instance running, we want to forward some ports through our home wifi router, host some images and map our domain to it points itself at our home&#39;s external IP address.</p>

<h2 id="setup-writefreely-to-host-images">Setup WriteFreely to Host Images</h2>

<p>I thought about throwing up a Pixelfed instance on this box – I have the disk space and the database. But I&#39;d have to futz around with the conflicting port addresses and mapping/forwarding through my firewall, or get into subdomain mapping like pixelfed.awadwatt.com etc.</p>

<p>I toyed around with setting up an Apache virtual host at awadwatt.com/img/ on a random port (remember WF already gloms 80 and 443) and was able to get that to work, but as I found out, linking to unsecure http images from within a WriteFreely page hosted in secure https throws browsers for a loop; I&#39;d have to run WF unsecure at port 80 for that to work or figure out how to get that virtual host, at a custom port (6900) to host https. Getting an Apache virtual host to do Secure HTTP NOT on port 443 was beyond my skills, or rather my patience. And having to type image URLs as <code>https://awadwatt.com:6900/img/file.png</code> got to be real tedious real fast.</p>

<p>Then I realized: <em>WriteFreely already hosts images (or static files anyway)! The little draft icon <img src="https://awadwatt.com/tez/blogs.png" alt="this">, the avatar icons, the (default) CSS stylesheets, the browser tab “favicon.ico” file etc.</em>
Sure enough, poking around in <code>/usr/local/bin/writefreely</code> there&#39;s a <code>statics</code> folder, and everything in there is addressable from the domain root. So we could just toss our images in the statics folder, but we can do better than that; for one, I didn&#39;t want my images folder trashed whenever I upgraded the application.</p>

<p>So I linked a user specific sub-folder from the <code>static</code> folder to where the images live and made sure the user that WriteFreely runs as can traverse it. Remember that samba folder I created earlier? yep:</p>

<pre><code>tezoatlipoca@famine:/usr/local/bin/writefreely/static&gt; ls -lat
total 16
drwxrwxr-x 1 tezoatlipoca tezoatlipoca  118 Mar  9 14:32 .
-rwxrwxrwx 1 root         root           53 Mar  9 14:29 google296e6456a3479f2c.html
lrwxrwxrwx 1 root         root           23 Mar  6 22:00 tez -&gt; /diskb/img/tezoatlipoca
drwxrwxr-x 1 tezoatlipoca tezoatlipoca   90 Mar  6 10:54 ..
drwxrwxr-x 1 tezoatlipoca tezoatlipoca   98 Nov 11 02:51 css
-rw-rw-r-- 1 tezoatlipoca tezoatlipoca 6090 Nov 11 02:51 favicon.ico
drwxrwxr-x 1 tezoatlipoca tezoatlipoca 1218 Nov 11 02:51 fonts
drwxrwxr-x 1 tezoatlipoca tezoatlipoca  852 Nov 11 02:51 img
drwxrwxr-x 1 tezoatlipoca tezoatlipoca  390 Nov 11 02:51 js
drwxrwxr-x 1 tezoatlipoca tezoatlipoca   20 Nov 11 02:51 local
</code></pre>

<p>So now (at least on my home network), all I have to do is save an image to <code>\\famine\img\tezoatlipoca</code> and it shows up at <code>http://awadwatt.com/tez/</code></p>

<p> Dunno how robust WF&#39;s static hosting will hold up under punishment, but I&#39;ve had a few img bearing posts get hit by a few hundred Mastodon instances and so far so good.</p>

<p>At some point Ill go back to that Apache virtual host method, I really want to get a CGI file uploading script working so I can upload images from work (without opening an ssh hole in my home router for sftp)</p>

<h2 id="port-forwarding">Port Forwarding</h2>

<p>Not too much to say here other than log into your home wifi/internet router and <em>forward</em> ports <code>80</code> (http) and <code>443</code> (https) to your WriteFreely instance host.</p>

<p>To diagnose that your host is reachable, use a service like <a href="https://whatismyipaddress.com/" rel="nofollow">https://whatismyipaddress.com/</a> to determine your wifi router&#39;s external IP address. Then, use your cell phone (disable the wifi!) or from work/school/somewhere not at home, try and connect to that IP address. If you see your WriteFreely instance, huzzah!</p>

<p>If not, check to see if those ports are open/being forwarded properly by probing those ports at that external IP address. <a href="https://www.grc.com/x/ne.dll?bh0bkyd2" rel="nofollow">The Shields Up! tool by Gibson Research</a> &gt; Scan “All system ports” has been around forever and its still good. The only ports you should see in red are 80 and 443:
<img src="/tez/port.map.PNG" alt="Shields Up map: only 80 and 443 are forwarded and responding == red"></p>

<h1 id="span-id-dns-domain-mapping-dynamic-dns-span"><span id="dns">Domain Mapping – Dynamic DNS</span></h1>

<p>Our last step is to set up DNS mapping to our external IP. You could call it quits here, I suppose, and just say, “hey, my blog is at ,” but any Federated service that picks up your blog posts will always expect to find it at the same domain location. Home IP addresses on fixed cable/fibre connections <em>tend</em> not to change too much, but you can never be sure that your IP <em>won&#39;t</em> change. Having a static DNS domain-&gt;IP address mapping solves that problem.</p>

<p>If our instance was hosted by, or colocated IN an ISP&#39;s data center, then yes, part of that hosting arrangement would be allocation of a fixed IP address.</p>

<p>Fortunately, there are (paid, cheap or free) <em>Dynamic DNS</em> services. Essentially these work in two steps:</p>
<ul><li>YOU modify your (or some) domain registration (GoDaddy.com, Network Solutions, wherever you registered it) so that its DNS <em>servers</em> of record (i.e. the ones who own the mapping) are the Dynamic DNS services&#39; servers.
<ul><li>now, when a computer wants to find yourdomain.org, it asks ITS upstream DNS server (wifi router, ISP etc.); the upstream DNS server know to ask Dynamic DNS&#39;s DNS server; it will know. How?</li></ul></li>
<li>YOU tell Dynamic DNS&#39;s servers what IP address to map yourdomain.org TO.
<ul><li>you can do this manually, or you can set up some automated job/process that runs periodically to update/confirm your server&#39;s IP address.</li></ul></li></ul>

<p>How you set this up will depend on the specific Dynamic DNS provider.</p>

<p>I used <a href="https://freedns.afraid.org/" rel="nofollow">https://freedns.afraid.org/</a> which has both free and paid tiers of dynamic DNS mapping. At my domain registrar, I changed my domain registration&#39;s DNS servers:</p>

<pre><code>Domain Name: AWADWATT.COM
Registrar WHOIS Server: whois.networksolutions.com
Registrar URL: http://networksolutions.com
Creation Date: 1999-08-25T21:28:32Z
&lt;snip&gt;
Name Server: NS1.AFRAID.ORG
Name Server: NS2.AFRAID.ORG
Name Server: NS3.AFRAID.ORG
Name Server: NS4.AFRAID.ORG
</code></pre>

<p>to theirs.</p>

<p>Then, an hourly cron (scheduled system task) job runs to update the afraid.org name servers with my external IP address. Easy!</p>

<p><strong>Just remember</strong> the SSL keys that <code>writefreely keys generate</code> depend on the domain address your instance is found at. So once you get your domain mapping up, be sure to go back and create secure https keys otherwise visiting clients/federated services will get TLS and SSL errors – the host/domain in the keys doesn&#39;t match how your server appears on the internet.</p>

<p><strong>Also</strong>: DNS propagation can take some time: several days. So don&#39;t be surprised after changing your domain &gt; DNS servers and setting up dynamic DNS mapping, it could take several hours to several days before your WriteFreely instance consistently is available at yourdomain.org.</p>

<h1 id="done-whats-left-feedback">Done! Whats left? Feedback</h1>

<p>That wasn&#39;t so bad? Figuring this out and flexing some long dormant linux skills took me maybe 6? 8? hours over a weekend. Im sure I could do this in just a few hours. I&#39;d still like to:</p>
<ul><li><em>try and get WriteFreely running on Windows</em>; there are some older Windows binaries available in various repositories, but supposedly its possible to compile from source. But getting a current Windows binary (or a MacOS one!) makes self-hosting available to so many more people.</li>
<li><em>figure out an image uploading mechanism</em> to complement my static subfolder link hack. For one, if I have guest accounts on my WF instance I&#39;d like to be able to offer them image hosting capabilities, without having to log into my home wifi to do it.</li>
<li><em>in-post table of contents using headers!</em> – sometime in the last week or so I saw a post from a Write.As user who figured out a way – using only CSS – to dynamically generate a table of contents of all the headers in your post; gotta dig that up.</li>
<li><a href="https://awadwatt.com/tezoatlipoca/customizing-the-css-for-writefreely-is-a-pain-in-the-butt" rel="nofollow"><em>experiment with CSS for customization</em> – DONE</a></li>
<li><a href="https://awadwatt.com/tezoatlipoca/putting-yarr-rss-reader-behind-nginx-reverse-proxy" rel="nofollow">Put behind NGINX</a></li></ul>

<h3 id="did-you-follow-this-did-it-work-problems">Did you follow this? Did It work? Problems?</h3>

<p>Seriously, I&#39;d love to hear from you. tezoatlipoca @ gmail.com or @tezoatlipoca @ mas.to.</p>

<h3 id="changelog">Changelog</h3>

<p>2023-03-07  – initial
2024-10-15 – CSS and NGINX links.</p>
]]></content:encoded>
      <guid>https://awadwatt.com/tezoatlipoca/federated-blog-writefreely-how-to-self-host-on-a-potato</guid>
      <pubDate>Tue, 07 Mar 2023 07:24:11 -0500</pubDate>
    </item>
    <item>
      <title>WriteFreely Writer&#39;s Guide - Cheat Sheet</title>
      <link>https://awadwatt.com/tezoatlipoca/writefreely-writers-guide-cheat-sheet</link>
      <description>&lt;![CDATA[The #writefreely Writer&#39;s Guide latest - over here is quite good, but I wanted a quick cheat sheet for formatting. Also, I have found that WriteFreely can support a bit more of the Markdown Standard, but not all of it. &#xA;&#xA;\!--more--\&#xA; snip (get rid of the \\&#39;s) -- truncates your post on the blog homepage with a &#34;Read more..&#34; link. &#xA;(everything above it makes the front page, everything below doesn&#39;t)&#xA;&#xA;# h1 Title&#xA;###### h6 title&#xA;italics or italics&#xA;bold bold&#xA;mix and match is ok&#xA;mix and match is ok&#xA;&#xA;` bullet1&#xA;bullet2&#xA; sub-bullet2.1`&#xA;&#xA;`1. list1&#xA;list2&#xA;if you reuse 1. it auto-numbers from last`&#xA;&#xA;IMAGE: image text maybe ALT text?&#xA;LINK: link text&#xA;EMAIL: email link&#xA;&#xA;  this stuff is&#xA;  quoted&#xA;&#xA;  this stuff is -- leave a blank line before to work properly&#xA;  quoted&#xA;&#xA;\this is code\&#xA;this is code&#xA;The backticks are greedy! (if you have \blah\ more text\`, all of your text will be glommed as code.&#xA;&#xA;HTML&#xA;Properly formatted and enclosed tags:&#xA;h1 (thru h4), p, ul, li, ol, blockquote, strong, em, u, span, div, a href&#xA;&#xA;Use spans and divs to have custom css styles. &#xA;span style=&#34;color:red&#34;Style/span&#xA;span style=&#34;color:red&#34;Style/span&#xA;&#xA;div id=&#34;myDiv&#34; name=&#34;myDiv&#34; title=&#34;Example Div Element&#34; style=&#34;color: #0900C4; border: 1px solid black;&#34;&#xA;  h5Subtitle in the box/h5&#xA;  pThis paragraph is also inside the box.../p&#xA;/div&#xA;&#xA;div id=&#34;myDiv&#34; name=&#34;myDiv&#34; title=&#34;Example Div Element&#34; style=&#34;color: #0900C4; border: 1px solid black;&#34;&#xA;  h5Subtitle in the box/h5&#xA;  pThis paragraph is also inside the box.../p&#xA;/div&#xA;&#xA;span id=&#34;Bookmarks&#34;Bookmarks (page links/anchors)/span&#xA;These let you make a jump from somewhere in your page to elsewhere. These are just old school HTML anchors, but because we edit in Markdown here we have to add some HTML to insert the anchor/bookmark id in our destination: &#xA;&#xA;Where you want to jump TO: wrap the destination text in a span id=&#34;bookmarkname&#34; /span tag. e.g (to this section):&#xA;&#xA;## span id=&#34;Bookmarks&#34;Bookmarks/span&#xA;&#xA;Where you want to jump FROM:* make an href but include the bookmark after a pound/hashtag sign:&#xA;&#xA;a href=&#34;#Bookmarks&#34;click here to jump to the Bookmarks section/a&#xA;&#xA;a href=&#34;#Bookmarks&#34;click here to jump to the Bookmarks section/a &lt;-- click on this should scroll back up to the top of this section. &#xA;&#xA;You can do this across sites or between your own WriteFreely pages: &#xA;&#xA;a href=&#34;writefreely-writers-guide-cheat-sheet#Bookmarks&#34;click here to jump to the Bookmarks section/a&#xA;&#xA;a href=&#34;writefreely-writers-guide-cheat-sheet#Bookmarks&#34;click here to jump to the Bookmarks section/a&#xA;&#xA;Extended Markdown Support in WriteFreely&#xA;WriteFreely supports some, but not all of the extended Markdown standard.&#xA;Horizontal Rule ok &#xA;---&#xA;---&#xA;Table ok&#xA;| Syntax | Description |&#xA;| ----------- | ----------- |&#xA;| Header | Title |&#xA;| Paragraph | bold Text  |&#xA;| Syntax | Description |&#xA;| ----------- | ----------- |&#xA;| Header | Title |&#xA;| Paragraph | bold Text |&#xA;&#xA;edit 23/6/24: Markdown tables only seem to work up to about page width, or about seven columns. &#xA;&#xA;You can use HTML tabletrtd.. notation but markdown inside won&#39;t render properly unless you use HTML markup:&#xA;&#xA;tabletheadtrtdhdr1/tdtdhdr2/td/tr/thead&#xA;trtdcell 1/tdtdbbold cell 2/b/td/tr&#xA;/table&#xA;tabletheadtrtdhdr1/tdtdhdr2/td/tr/thead&#xA;trtdcell 1/tdtdbbold cell 2/b/td/tr&#xA;/table&#xA;---&#xA;Fenced Code Block ok&#xA;&#xA;~&#xA;{&#xA;  &#34;firstName&#34;: &#34;John&#34;,&#xA;  &#34;lastName&#34;: &#34;Smith&#34;,&#xA;  &#34;age&#34;: 25&#xA;}&#xA;~&#xA;&#xA;{&#xA;  &#34;firstName&#34;: &#34;John&#34;,&#xA;  &#34;lastName&#34;: &#34;Smith&#34;,&#xA;  &#34;age&#34;: 25&#xA;}&#xA;---&#xA;Footnote not&#xA;&#xA;Here&#39;s a sentence with a footnote. &#xA;&#xA;: This is the footnote.&#xA;Here&#39;s a sentence with a footnote. &#xA;&#xA;: This is the footnote.&#xA;---&#xA;Heading ID not&#xA;&#xA;### My Great Heading {#custom-id}&#xA;### My Great Heading {#custom-id} &#xA;---&#xA;&#xA;Definition List not&#xA;&#xA;term&#xA;: definition &#xA;term&#xA;: definition &#xA;---&#xA;Strikethrough ok&#xA;The world is flat. &#xA; The world is flat. &#xA;---&#xA;Task List not&#xA;[x] Write the press release&#xA;[ ] Update the website&#xA;[ ] Contact the media&#xA;[x] Write the press release&#xA;[ ] Update the website&#xA;[ ] Contact the media &#xA;&#xA;---&#xA;Emojis  not&#xA;That is so funny! :joy: &#xA;That is so funny! :joy: &#xA;---&#xA;Highlight  not&#xA;the following 3 ==words are very== important &#xA;the following 3 ==words are very== important  &#xA;---&#xA;Superscript not&#xA;x^2^ &#xA;x^2^ &#xA;&#xA;Changelog&#xA;2023-03-05 - initial&#xA;2023-06-24 - discovered markdown tables break around column 8 or so. added note. ]]&gt;</description>
      <content:encoded><![CDATA[<p>The <a href="/tezoatlipoca/tag:writefreely" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">writefreely</span></a> Writer&#39;s Guide <a href="https://writefreely.org/docs/latest/writer" rel="nofollow">latest – over here</a> is quite good, but I wanted a quick cheat sheet for formatting. Also, I have found that WriteFreely can support a bit more of the <a href="https://www.markdownguide.org/cheat-sheet/" rel="nofollow">Markdown Standard</a>, but not all of it.</p>

<p><code>\&lt;!--more--\&gt;</code>
 snip (get rid of the \&#39;s) — truncates your post on the blog homepage with a “Read more..” link.
(everything above it makes the front page, everything below doesn&#39;t)</p>

<p><code># h1 Title</code>
<code>###### h6 title</code>
<code>*italics* or _italics_</code>
<code>**bold** __bold__</code>
<em>mix and <strong>match</strong> is ok</em>
<code>_mix and **match** is ok_</code></p>

<p><code>* bullet1
* bullet2
 * sub-bullet2.1</code></p>

<p><code>1. list1
2. list2
1. if you reuse 1. it auto-numbers from last</code></p>

<p>IMAGE: <code>![image text maybe ALT text?](http://url/)</code>
LINK: <code>[link text](http://link url)</code>
EMAIL: <code>[email link](mailto:me@somewhere.org)</code></p>

<p><code>&gt; this stuff is</code>
<code>&gt; quoted</code></p>

<blockquote><p>this stuff is — leave a blank line before to work properly
quoted</p></blockquote>

<p>`this is code`
<code>this is code</code>
The backticks are greedy! (if you have `blah` more text`, all of your text will be glommed as code.</p>

<h2 id="html">HTML</h2>

<p>Properly formatted and enclosed tags:
<code>h1 (thru h4), p, ul, li, ol, blockquote, strong, em, u, span, div, a href</code></p>

<p>Use spans and divs to have custom css styles.
<code>&lt;span style=&#34;color:red&#34;&gt;Style&lt;/span&gt;</code>
<span style="color:red">Style</span></p>

<pre><code>&lt;div id=&#34;myDiv&#34; name=&#34;myDiv&#34; title=&#34;Example Div Element&#34; style=&#34;color: #0900C4; border: 1px solid black;&#34;&gt;
  &lt;h5&gt;Subtitle in the box&lt;/h5&gt;
  &lt;p&gt;This paragraph is also inside the box...&lt;/p&gt;
&lt;/div&gt;
</code></pre>

<div id="myDiv" title="Example Div Element" style="color: #0900C4; border: 1px solid black;">
  <h5>Subtitle in the box</h5>
  <p>This paragraph is also inside the box...</p>
</div>

<h2 id="span-id-bookmarks-bookmarks-page-links-anchors-span"><span id="Bookmarks">Bookmarks (page links/anchors)</span></h2>

<p>These let you make a jump from somewhere in your page to elsewhere. These are just old school HTML anchors, but because we edit in Markdown here we have to add some HTML to insert the anchor/bookmark id in our destination:</p>

<p><em>Where you want to jump TO:</em> wrap the <em>destination</em> text in a <code>&lt;span id=&#34;bookmarkname&#34;&gt; &lt;/span&gt;</code> tag. e.g (to this section):</p>

<p><code>## &lt;span id=&#34;Bookmarks&#34;&gt;Bookmarks&lt;/span&gt;</code></p>

<p><em>Where you want to jump FROM:</em> make an href but include the bookmark after a pound/hashtag sign:</p>

<p><code>&lt;a href=&#34;#Bookmarks&#34;&gt;click here to jump to the Bookmarks section&lt;/a&gt;</code></p>

<p><a href="#Bookmarks" rel="nofollow">click here to jump to the Bookmarks section</a> &lt;— click on this should scroll back up to the top of this section.</p>

<p>You can do this across sites or between your own WriteFreely pages:</p>

<p><code>&lt;a href=&#34;writefreely-writers-guide-cheat-sheet#Bookmarks&#34;&gt;click here to jump to the Bookmarks section&lt;/a&gt;</code></p>

<p><a href="writefreely-writers-guide-cheat-sheet#Bookmarks" rel="nofollow">click here to jump to the Bookmarks section</a></p>

<h1 id="extended-markdown-support-in-writefreely">Extended Markdown Support in WriteFreely</h1>

<p>WriteFreely supports some, but not all of the <a href="https://www.markdownguide.org/cheat-sheet/" rel="nofollow">extended Markdown standard</a>.</p>

<h3 id="horizontal-rule-ok-tez-ok-png">Horizontal Rule <img src="/tez/ok.png" alt="ok"></h3>

<p><code>---</code></p>

<hr>

<h3 id="table-ok-tez-ok-png">Table <img src="/tez/ok.png" alt="ok"></h3>

<pre><code>| Syntax | Description |
| ----------- | ----------- |
| Header | Title |
| Paragraph | **bold Text**  |
</code></pre>

<table>
<thead>
<tr>
<th>Syntax</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td>Header</td>
<td>Title</td>
</tr>

<tr>
<td>Paragraph</td>
<td><strong>bold Text</strong></td>
</tr>
</tbody>
</table>

<p><em>edit 23/6/24: Markdown tables only seem to work up to about page width, or about seven columns.</em></p>

<p>You <em>can</em> use HTML <code>&lt;table&gt;&lt;tr&gt;&lt;td&gt;..</code> notation but markdown inside won&#39;t render properly unless you use HTML markup:</p>

<pre><code>&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;hdr1&lt;/td&gt;&lt;td&gt;hdr2&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;**cell 1**&lt;/td&gt;&lt;td&gt;&lt;b&gt;bold cell 2&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</code></pre>

<p><table><thead><tr><td>hdr1</td><td>hdr2</td></tr></thead>
<tr><td><strong>cell 1</strong></td><td><b>bold cell 2</b></td></tr>
</table></p>

<hr>

<h3 id="fenced-code-block-ok-tez-ok-png">Fenced Code Block <img src="/tez/ok.png" alt="ok"></h3>

<pre><code>```
{
  &#34;firstName&#34;: &#34;John&#34;,
  &#34;lastName&#34;: &#34;Smith&#34;,
  &#34;age&#34;: 25
}
```
</code></pre>

<pre><code>{
  &#34;firstName&#34;: &#34;John&#34;,
  &#34;lastName&#34;: &#34;Smith&#34;,
  &#34;age&#34;: 25
}
</code></pre>

<hr>

<h3 id="footnote-not-tez-not-png">Footnote <img src="/tez/not.png" alt="not"></h3>

<pre><code>Here&#39;s a sentence with a footnote. [^1]

[^1]: This is the footnote.
</code></pre>

<p>Here&#39;s a sentence with a footnote. [^1]</p>

<p>[^1]: This is the footnote.</p>

<hr>

<h3 id="heading-id-not-tez-not-png">Heading ID <img src="/tez/not.png" alt="not"></h3>

<p><code>### My Great Heading {#custom-id}</code></p>

<h3 id="my-great-heading-custom-id">My Great Heading {<a href="/tezoatlipoca/tag:custom" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">custom</span></a>-id}</h3>

<hr>

<h3 id="definition-list-not-tez-not-png">Definition List <img src="/tez/not.png" alt="not"></h3>

<p><code>term</code>
<code>: definition</code>
term
: definition</p>

<hr>

<h3 id="strikethrough-ok-tez-ok-png">Strikethrough <img src="/tez/ok.png" alt="ok"></h3>

<p><code>~~The world is flat.~~</code>
 <del>The world is flat.</del></p>

<hr>

<h3 id="task-list-not-tez-not-png">Task List <img src="/tez/not.png" alt="not"></h3>

<pre><code>- [x] Write the press release
- [ ] Update the website
- [ ] Contact the media
</code></pre>
<ul><li>[x] Write the press release</li>
<li>[ ] Update the website</li>
<li>[ ] Contact the media</li></ul>

<hr>

<h3 id="emojis-not-tez-not-png">Emojis  <img src="/tez/not.png" alt="not"></h3>

<p><code>That is so funny! :joy:</code>
That is so funny! :joy:</p>

<hr>

<h3 id="highlight-not-tez-not-png">Highlight  <img src="/tez/not.png" alt="not"></h3>

<p><code>the following 3 ==words are very== important</code>
the following 3 ==words are very== important</p>

<hr>

<h3 id="superscript-not-tez-not-png">Superscript <img src="/tez/not.png" alt="not"></h3>

<p><code>x^2^</code>
x^2^</p>

<h1 id="changelog">Changelog</h1>

<p>2023-03-05 – initial
2023-06-24 – discovered markdown tables break around column 8 or so. added note.</p>
]]></content:encoded>
      <guid>https://awadwatt.com/tezoatlipoca/writefreely-writers-guide-cheat-sheet</guid>
      <pubDate>Sun, 05 Mar 2023 16:23:08 -0500</pubDate>
    </item>
  </channel>
</rss>