{"id":4220,"date":"2018-05-04T22:47:49","date_gmt":"2018-05-04T20:47:49","guid":{"rendered":"https:\/\/sunpig.com\/martin\/?p=4220"},"modified":"2018-06-05T21:39:02","modified_gmt":"2018-06-05T19:39:02","slug":"microblogging-2","status":"publish","type":"post","link":"https:\/\/sunpig.com\/martin\/2018\/05\/04\/microblogging-2\/","title":{"rendered":"Microblogging"},"content":{"rendered":"<p>When it comes to my online lifestyle, I&#8217;m quite stodgy and old-fashioned. I like having a domain that is the canonical digital representation of me. I like running software on my own server, so that I&#8217;m in control of my own content. I prefer writing here, and having the words copied to Twitter rather than the other way around. Over the years I&#8217;ve been guilty of tweaking the URL structure here on sunpig.com (<a href=\"https:\/\/www.w3.org\/Provider\/Style\/URI\">cool URIs don&#8217;t change<\/a>), but I have tried to keep redirects in place for old content. The last change was four years ago when I <a href=\"https:\/\/sunpig.com\/martin\/2014\/01\/05\/moving-to-wordpress\/\">moved from Movable Type to WordPress<\/a> and settled on the  sunpig.com\/martin\/year\/month\/day\/slug\/ format, dropping the &#8220;.html&#8221; suffix. I&#8217;m quite particular about my URLs.<\/p>\n<p>And I really like WordPress! But compared to the ease of putting up a Tweet, it has always felt overcomplicated. Now that I have a lovely new (actually, not that new any more, but it still <em>feels<\/em> new) <a href=\"https:\/\/sunpig.com\/martin\/2018\/01\/28\/nice-things-2017\/\">iPhone X<\/a> that is capable of great feats of computing, I&#8217;ve been wanting to post to my blog more often, and more casually. And while there is a WordPress app for iOS, the image upload  workflow had me stymied for a long time.<\/p>\n<p>See, I don&#8217;t use WordPress&#8217;s built-in image uploading capabilities, because it puts uploaded images in the <em>wrong place<\/em>. By default, WordPress puts them under <code>\/...\/wordpress\/wp-content\/uploads\/sites\/$SITE_ID\/$YEAR\/$MONTH\/<\/code>. I don&#8217;t like storing CMS <em>content<\/em> in the directory structure of the application itself. It feels like I&#8217;m tying myself to the application, and I hate that. (I also still write my HTML by hand, rather than using WordPress&#8217;s visual editor. Like I said, stodgy and old-fashioned. It&#8217;s also a position of privilege, and I&#8217;m aware of that.) Uploaded images should be served from <code>https:\/\/sunpig.com\/martin\/images\/$YEAR\/<\/code>, and I want them stored on disk in a location that maps closely to that same structure. So until today, my image workflow had been:<\/p>\n<ul>\n<li>Take picture.<\/li>\n<li>Manipulate picture, usually in <a href=\"https:\/\/flyingmeat.com\/acorn\/\">Acorn<\/a>.<\/li>\n<li>Save suitably compressed picture to a folder on disk that has an <a href=\"https:\/\/support.apple.com\/en-gb\/guide\/automator\/welcome\/mac\">OSX Automator<\/a> folder action on it that does an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rsync\"><code>rsync<\/code><\/a> upload of any new files to the matching folder on my server. (Or, if I&#8217;m not on my home computer, use <a href=\"https:\/\/panic.com\/transmit\/\">Transmit<\/a> to do the upload manually.) Because I&#8217;ve got nginx serving images direct from disk, that image is now immediately available over https.<\/li>\n<li>In WordPress, use the &#8220;Add Media&#8221; option to &#8220;insert from URL&#8221;, <em>manually typing out<\/em> the URL where I know the image lives.<\/li>\n<li>Save the blog entry.<\/li>\n<\/ul>\n<p>If this is tedious on a desktop machine, it&#8217;s ten times worse on a phone. On iOS there are plenty of really nice image editors; fewer options for scaling and optimizing images for the web; and only a few apps I&#8217;d feel happy entrusting with my ssh keys for connecting to remote servers. With Panic Software <a href=\"https:\/\/panic.com\/blog\/the-future-of-transmit-ios\/\">sunsetting Transmit for iOS<\/a> I didn&#8217;t see the workflow getting any better. I briefly contemplated writing my own app that would do all of this in a single gulp, but&#8230;I&#8217;ve got better things to do with my time.<\/p>\n<p>Today I was messing around with <a href=\"https:\/\/micro.blog\">micro.blog<\/a>, whose <a href=\"http:\/\/help.micro.blog\/2015\/why-i-created-this\/\">concept<\/a> I love, and which I backed on <a href=\"https:\/\/www.kickstarter.com\/projects\/manton\/indie-microblogging-owning-your-short-form-writing\">Kickstarter<\/a>. I installed the iOS app because it supports posting directly to a WordPress blog. But then I ran into the upload problem again: if I upload an image from any third-party application, WordPress would just put it in its own stupid location, and I wouldn&#8217;t be any better off.<\/p>\n<p><em>Sigh.<\/em><\/p>\n<p>But I dug a bit deeper and found that there&#8217;s actually a pretty simple answer to this. One of the great things about WordPress is how <em>madly customizable<\/em> it is. Pretty much every function in the application can be tweaked or completely overridden through the use of <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Filter_Reference\/\">filter hooks<\/a>, and this includes the location of file uploads. In the end, I created a <a href=\"https:\/\/codex.wordpress.org\/Child_Themes\">child theme<\/a> to hold my customizations, so that they won&#8217;t get overwritten when the parent theme is updated. In the child theme, I add a filter to the built-in <code>upload_dir<\/code> function that will replace the default upload locations with my preferred locations:<\/p>\n<pre><code>\/\/ Customize the uploads directory:\r\n\/\/ By default, WP uploads to $WORDPRESS_DIR\/wp-content\/uploads\/sites\/$SITE_ID\/$YEAR\/$MONTH\/\r\n\/\/ I want to upload to $BLOG_ROOT\/images\/$YEAR\/\r\n\/\/\r\n\/\/ The $uploads parameter contains details of the uploads directory and the\r\n\/\/ path on which uploaded files will be served. Default:\r\n\/\/ {\r\n\/\/     \"path\":\"\/var\/www\/sunpig.com\/wordpress\/wp-content\/uploads\/sites\/2\/2018\/05\",\r\n\/\/     \"url\":\"https:\/\/sunpig.com\/martin\/wp-content\/uploads\/sites\/2\/2018\/05\",\r\n\/\/     \"subdir\":\"\/2018\/05\",\r\n\/\/     \"basedir\":\"\/var\/www\/sunpig.com\/wordpress\/wp-content\/uploads\/sites\/2\",\r\n\/\/     \"baseurl\":\"https:\/\/sunpig.com\/martin\/wp-content\/uploads\/sites\/2\",\r\n\/\/     \"error\":false\r\n\/\/ }\r\nfunction sunpig_martin_upload_dir_filter( $uploads ) {\r\n    $year = date(\"Y\");\r\n    $uploads['basedir'] = \"\/var\/www\/sunpig.com\/martin\/images\";\r\n    $uploads['baseurl'] = \"https:\/\/sunpig.com\/martin\/images\";\r\n    $uploads['path'] = \"\/var\/www\/sunpig.com\/martin\/images\/$year\";\r\n    $uploads['url'] = \"https:\/\/sunpig.com\/martin\/images\/$year\";\r\n    $uploads['subdir'] = \"\/$year\";\r\n\r\n    return $uploads;\r\n}\r\n\r\nadd_filter( 'upload_dir', 'sunpig_martin_upload_dir_filter' );<\/code><\/pre>\n<p>And boom ? WordPress now puts my uploaded images exactly where I want. I could have done this more elegantly, with less hard-coding, but LOL no. This is perfectly fine.<\/p>\n<p><b>UPDATE 5 June 2018:<\/b> Putting this functionality in a <em>child theme<\/em> is the wrong place, because it means that I have to make a new child theme whenever I want to change the theme of my blog. The <em>right place<\/em> for this code to go is in a <a href=\"https:\/\/css-tricks.com\/wordpress-functionality-plugins\/\">functionality plugin<\/a> that can operate no matter what theme is active. <\/p>\n<p>The WordPress app and the Micro.blog app now sit on the home screen of my phone. I like the &#8220;messing around in photo apps&#8221; part of my blogging workflow &#8211; that bit was never the problem. Now that I&#8217;ve fixed the image uploading step, I hope that this means I&#8217;ll post more often, and in smaller chunks. We&#8217;ll see!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When it comes to my online lifestyle, I&#8217;m quite stodgy and old-fashioned. I like having a domain that is the canonical digital representation of me. I like running software on my own server, so that I&#8217;m in control of my own content. I prefer writing here, and having the words copied to Twitter rather than &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/sunpig.com\/martin\/2018\/05\/04\/microblogging-2\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Microblogging&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-4220","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts\/4220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/comments?post=4220"}],"version-history":[{"count":13,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts\/4220\/revisions"}],"predecessor-version":[{"id":4373,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/posts\/4220\/revisions\/4373"}],"wp:attachment":[{"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/media?parent=4220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/categories?post=4220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sunpig.com\/martin\/wp-json\/wp\/v2\/tags?post=4220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}