• Two Memories About Trees

    Where I live in Yokohama we have some small forests that they've decided to turn into parks. There's some paths through them, they're nice. I'm not sure if they're "native" forests or not, but the patches of green are nice.

    Trees are something I've found myself become more of an advocate for as I've gotten older. We need more of them. Not just for the carbon capture features, but for the purely practical reasons: their shade helps cool us down and they clean the air. There's also some psychological benefits of seeing green, too.


    Growing up in southern California, our house was a typical post-war ranch style house. In the back we had 3 big lemon trees that produced more lemons that any person could consume. Out front the entire street was lined with tree.  Most houses didn't have trees in their yards because of these mature trees provided shade most of the day. It was great when you were playing outside, riding your bikes and skateboards.

    But these trees roots were deep and apparently starting to interfere with some plumbing. So the city decided to cut them all down. They replaced them with these young trees that looked like toothpicks in comparison.

    The difference in street temperature and the harshness of the light being outside was immediate. Without trees to filter the sun going outside your house you were blinded be the light. The rest of the neighborhood kept their trees, just ours became this hot barren wasteland.

    But it's been 20 years. Writing this post I looked at street view on Google maps to see what has changed. All of the trees on my street have gotten bigger and can provide enough shade for a single parked car. Except the one in front of my old house. It's still a twig (or more likely got replaced again). The city also seems to have found their way to the rest of the neighborhood as there's not much shade along the sidewalks anywhere anymore.


    One of my favorite summer treats were tips to Knotts Berry Farm, an amusement park.  The day before we'd go we'd visit the local Vons and pickup sub rolls, deli meats, and other sandwich fixin's. We take the van (a Ford Econoline). This van had 2.5 rows for seating: two seats up front, a bench in the back, and a single seat in the middle, giving you a nice open area around the sliding door.

    Knott's has multiple parking lots, but one of them was park-like and almost entirely covered in shade. We'd park there with a big cooler full of sandwich goods and drinks. During lunch we'd leave the park, enjoy the breeze, and have a nice picnic in the van. 

    Sometimes, even with the trees, it was a bit warm. On those days we'd have our "Texas coolers" (a cool/ice cool wet tea towel wrapped around our neck) help. Without those trees any picnic would have been hot and miserable.


    I don't really have a way to end this post. I just always think about trees and heat island effect more during summer and these two memories of growing up resurfaced themselves. 
  • Gathering Requirements for Native Crossposting in Tanzawa

    Ru made a feature request for Tanzawa to be able to syndicate / cross post from Tanzawa to other sites natively. I think it's a great idea and spent some time to collect my thoughts about what that could look like.

    My thoughts were posted on GitHub, but I'm copying them here so I always have a copy and in case people who read my blog but don't follow  the Tanzawa GitHub have any input.


    Agreed – being able to syndicate content directly from Tanzawa would be ideal. All syndication is currently manual (it doesn't hurt enough to automate it, yet).

    Base Thoughts 

    If we can figure out what the workflow would look like, I think we can define some base requirements for the feature. A couple of general thoughts about syndication:

    • I don't think posting should be syndicated automatically on publish. There's a couple of reasons for this: 
      • Tanzawa doesn't support any kind of background tasks. Posts that have a bunch of links take a while to complete it tries to send webmentions. Adding more external requests could increase the response time to longer than the request timeout allows quite easily. This is especially true because webmentions require 2 requests per save (before content update and after content update). We could probably process webmentions concurrently to speed this up, but that feels like a bit much at this point? It may be easy with asyncio, but I'd need to research it.
      • When I was posting with Wordpress there was a syndication checkbox (via brid.gy) and found it you'd get errors if you saved twice as the post had already been syndicated. Because there also wasn't a preview, it was always a bit of a gamble for how it would post.
    • Syndication is a separate concern from authoring posts themselves. And as such warrants dedicated screens to make it _right_.  Initially I had thought it might work well to handle syndication via a modal on the edit post page, but the more I think about it, it would box us in.
    • Brid.gy is still super handy for backfeeding likes/replies as webmentions. I still think brid.gy is useful / "required" unless we were to build in some kind of polling mechanism, which is difficult without support for cron/background tasks. ( It could be done "easily" with a django management command, I'm hesitant to introduce undue complexity).
    • "Syndication" feels a bit jargony to me. Is "Cross post" (or something similar)  a better term to use in the interface?
    • Each syndication destination is going to require some kind of settings (API keys, mostly). These can / should be managed via the Django admin?


    Create of  Syndication/Cross Posts

    This is assuming that all syndication can be handled with the same form.

    • Creating a new syndication would happen from the edit post button. The button should be on the meta menu (on the right), below the publish  buttons and only display once the post is published (you can't syndicate a draft).
    • Clicking this button would take you to dedicated syndication page.
    • The top of the page would be a form. The form would display the syndication text and up to 4 photos (with the caption).

      The syndication text is free text and pre-filled with either the post title + link or the first 280 chars of the note. Above the text field itself would be a segmented control (tabs? radio button?) that when clicked would let you toggle between the different presets.

      You may not want to syndicate each photo, so perhaps a checkbox is warranted to let you select which photos will be sent.
    • Finally at the bottom there's some checkboxes for which networks to syndicate to. As you can only syndicate a post once per network, posts that have already been syndicated to would be disabled with text explaining that you've already syndicated to that network for this post.
    • Once syndicated they'd store the url of the syndication and create a TSyndication record.

    Syndication List

    I think we'd want a separate section for syndication, like we do with "Posts / Files" on the left for syndications / cross posts. 

    Clicking that would show you a list of your most recent syndication activity ( syndication destination (link to twitter etc..), syndicated text, link to the related post). 

    Selecting a crosspost would show you a (readonly?) version of the syndication Create form.


    Does that sound about right? Anything you'd change or we should consider (especially regards to Mastodon,  I don't have an account/haven't used it before).
  • Writing Professionally in a Second Language

    I just finished an article that will be published in this month's Web+DB Press magazine, a monthly web-related programming magazine in Japan. The entire magazine, including my article, is in Japanese. I want to reflect on the process of writing professionally in a second language and contrast this with my first experience when writing the 2nd chapter of Professional Python Programming 3rd edition (PyPro3).

    Picking a Topic

    Unless you're writing for yourself, the general topic is going to be decided for you. The company I work for writes regularly for Web+DB Press. GraphQL's been gaining popularity lately, and since I've built a few projects with it, a co-worker asked if I was interested in writing an article about GraphQL. Remembering how difficult it was to write PyPro3, I was a bit hesitant at first, but thought it'd be a good test to see how much my Japanese had I'd improved over the years. I also wanted share what I'd learned building GraphQL APIs with Django.


    Outlining is the process where you set the scope and decide in in more detail what you want to write about and the general order that you'll write. Before you can start outlining you need to first decide roughly how long of an article you want to write. The length of a magazine article is often decided for you, so it's mostly a matter of figuring out what you can fit into the allocated space.

    My outline was fairly basic, just a bullet list to help guide me along as I wrote and the base idea for what we'd build in the article.


    Writing in your first language is difficult enough. Writing in a second language maintains the challenges of writing in your first, but also adds an extra layer on top. Not all idioms or expressions in your native language can be expressed in eloquently or in a similar manner in a different language.

    Having a solid outline of what you're going to write about, including the order and main points you want to cover makes writing much easier. This applies to writing in your first language as well, but it's doubly important in a second language.

    When writing PyPro3, I could write and speak Japanese, but writing a narrative piece was difficult. Many of the words I was using weren't quite yet internalized and reading what I wrote 5 minutes prior was a challenge. So I ended up writing the gist of what I wanted to say in English, and then translating it as best as I could before a native speaker cleaned it up for me.

    This time around, 3 years later, my outline was in Japanese and I didn't write any of the article in English first and then translate. Writing was a lot quicker too as I had become used to explaining code and what it's doing from work. I made the quickest progress when I was focusing on writing for a specific co-worker and explaining GraphQL to them.


    Editing in a second language is difficult. I won't say I'm useless, but I don't have that feeling when something sounds "off" like I do with English. Without that sense, it was difficult to know exactly how to fix feedback from internal reviews and the editor at the magazine.

    The actual process of editing this time around was much easier, however. A co-worker and I would pair edit, where I'd pull up the document on my screen via Zoom and we'd work through the comments together. This made it much easier to ask for advice or for clarification or a second opinion. 

    Beyond not having a native feel for the language, skimming is also much more difficult. This makes finding the paragraph a particular comment is referencing a bit slow. I got better as I practiced, but I also found that copying a snippet of the comment and using the Find feature of my editor helped immensely. 


    Good writing in any language requires clear thinking and proper planning. Being able to stay in the same language for planning, drafting, and editing makes the entire process much easier. Having native speakers check and edit your work  allows you to gain a better understanding of your second language, not only at the grammatical level, but with sentence patterns and flow as well.

    I'm grateful to have been given the opportunity to be published, especially in my non-native language and hope I'll have another chance in the future.
  • 🏔Tanzawa is Public 🎉

    Over the past few months I've been talking about the release of Tanzawa. And over these few months I keep on building up what the first release needs to be in my head. It must: 

    • not have any bugs
    • be easy to use
    • have proper documentation for getting started

    and so on and so forth. I keep on finding new things to add or fix that are "must haves" and so I keep on finding reasons to delay the release. And it's slowly been adding a bit of self-induced stress.

    No more.

    Tanzawa is now open source. It lives on GitHub at jamesvandyne/tanzawa. It has bugs. It has a bunch of edges rough enough to cut you. It has zero documentation for how to install and use it.

    But I'll address them overtime. And eventually, someday,  it will reach my vision of being a simple and sustainable  home on the web.

    If you need help or have questions or want to lend a hand: reply here, ping me on twitter @jamesvandyne, or open an issue.

    Tanzawa is public
  • Picking a License for Tanzawa

    As Tanzawa is getting closer to being something I can release for other people to use, I've been trying to decide on the best license for it and my goals for the project. The most likely scenario is that Tanzawa will only power my blog or a handful of blogs and that I'll be the only regular contributor. I'd love to be proven wrong, though 😀.

    My main goal for Tanzawa is to provide a system that slightly-technical folks can use to create their own home online. My secondary goal is to explore low-resource computing and using Tanzawa as my proving ground. If I can find a model that would allow me to build a revenue stream around Tanzawa, that would be great, but it's not a primary focus.

    I've considered all of the main open source licenses: Apache, AGPL, MIT, and BSD-3.  Each license is appealing to me for different ideological reasons. 

    Before researching licenses a bit, I had thought I would pick the AGPL. I really like changes would need to be released to the community. Wordpress uses the GPL, too. 

    But then I started thinking about the possibility of building software around Tanzawa to support paid hosting for Tanzawa blogs. This bit wouldn't be open source and it may require some custom hooks into Tanzawa. Picking the AGPL would lock me in needing to release these changes. Being the original author, I could just dual license it to myself, but it gets a bit murkier if anyone contributes to the project.

    I considered the MIT and BSD licenses together. BSD is basically public-domain in my mind. You're free to use Tanzawa how you please and keep all your changes to yourself. I'm not entirely opposed to this, and I'm sure it happens in reality with GPLed code. This said if someone uses Tanzawa to build something, I'd like them to acknowledge that what they've built is built on Tanzawa.  While I think scenario is a low probability, it's not zero.

    The last license I considered is the Apache license. What sets it apart from other licenses is its stance on software patents. Basically is someone contributes to Tanzawa and then sues me (again, low probability), they lose their right to use the software. But not being able to be sued gives me a piece of mind I can't get with the other licenses.

    Now to merge license files into the repository.
  • Re: Ode to my flip phone

    Reading Ode to my flip phone reminded me of Frank in You've Got Mail, singing the praises of his typewriter as everyone is getting computers and getting online. Society, for better or worse, has picked a new technological successor and the old ways – your flip phone, your typewriter, will eventually disappear.

    But this line – this line hit me hard.
    And by privacy I don’t mean cookies or my Social Security number or whatever—I mean the fragile sphere of imagination in which I exist when I’m not diddling about online. I mean what’s left of my nondigital self. When I clack your two halves shut, you glorious techno-mollusk, that’s it. Sauron cannot see me.
  • Build Open Systems And Maintain The Promise For Future Generations

    Growing up in the 90's, tech and the internet promised us open-data and open-systems. With a good idea and a bit of know-how could do most anything. And for a while that was true. But over time the systems have been slowly closed off.

    Even if you put your data into their systems you can only retrieve it under their terms. If you can even retrieve it. Formats are opaque or undocumented. API access could be revoked at any time for any reason with little or no recourse on your part.

    In other words: your data isn't yours. And you're certainly not free to do with it what you please. 

    Why do people subject themselves to this unfair and unequal status-quo? I'd argue that it's because how people view tech, including within the tech circle, has changed. 

    You can draw a line: Hackers vs The Social Network.

    If you watched Hackers, Sneakers, or Wargames in high school, you likely remember that promise of open-systems and open-data. You also see that promise being reneged one company after another. You may not feel it's as important as it once was, because, let's be real, goofing around on "free" services is easy and fun.

    However if your high school movie was The Social Network, you likely see the current state of tech as normal. Like a fish in water. Those VC companies neglected to mention the promise of the internet. In fact, the idea that your data is yours may not even be something that crosses your mind. Why should it? Nobody talks about it, so it must not be important. But it is.

    One of my major motivations for building Tanzawa is to help us regain control of our data and help uphold the promise back.  Want to visualize your Tanzawa data for a new project? Point your project to your Tanzawa db (or make a copy of it) and you can do whatever you want.

    The promise of open-systems and open-data isn't a given.  The default is closed. Or at least open until you're big enough consolidate and centralize. It's up to each of us to be stewards of an open internet. It's up to each of us support an open and free internet.

    Build open systems and maintain the promise for future generations.
  • Raising Awareness for the Carbon Cost of our Systems

    One of my original reasons for building Tanzawa was I wanted a blogging engine that, while pleasant to use, put a hard focus on efficiency for the express purpose of reducing carbon emissions. This has informed a number of architecture decisions in Tanzawa itself: no big background tasks, no db server, only make optimized images on their first request to save disk / cpu and more.

    To bring this in to focus, each page on Tanzawa has a badge that from websitecarbon.com that measures and reports the amount of carbon required to get that page from my server in Germany to you. It's not perfect, but it raises awareness.

    I don't run any analytics on my site, so I have no idea how often people click on things on my site, but my buddy mario saw I post I wrote and  decided to test his own fusioncast.fm website.

    Mario is using carbon as a guide in his website redesign

    This is the first documented instance I have of people being inspired to reduce the carbon impact of their sites based on my work! One site down, a million left :)
  • First Days with Tanzawa

    This was my first week using Tanzawa to power my actual blog and not just the dev blog. So far it's been great. I love how easy it is to post. I love that my site is IndieWeb native. I love that my site's stability has improved because I no longer require a database server. And I love that it's using fewer resources. It's great.

    This said, there's been a few rough edges that need polishing. Approving 50 some-odd webmentions after OwnYourSwarm started importing un-sent checkins required 50 some-odd page loads. Ouch. 

    I'd also like to improve site performance more in respect to images. Currently Tanzawa automatically requests the most efficient image format that your browser supports. Image format selection is all handled by the browser automatically (no Javascript). This alone usually cuts transfer size in half.

    While cutting the transfer size in half with a format change is a good start, I still don't need to be serving (at times) 4000px wide images. This is noticeable in streams where posts usually have images ( Checkins etc..) where the text loads instantly, but the progress bar lingers while images load.

    Rather, I'm going to change it to serve a resized (max 800px wide? ) image unless the original is specifically requested.

    Lastly, I want to start building a list of things that must (not should) be done before I can feel comfortable releasing Tanzawa for others to use and then start working on that list bit-by-bit.
  • Planning the Wordpress Migration

    The next big challenge for Tanzawa, and the last thing required for me to switch to it, is import my data from my existing Wordpress blog. There's 4 major parts to this challange:

    1. Parsing the Wordpress export XML file
    2. Figuring out how to map Wordpress posts to Tanzawa posts
    3. Downloading and importing media
    4. Rewriting existing posts to use these new asset urls and fix links.

    The first step is the easiest. I've figured out the basics of it yesterday using Beautiful Soup, but will require more exploration of the various posts before I can decide how to properly map data.

    The other steps are managable, but wrapped up in a 5th challenge –  managing the entire import process itself. Initially I had planned on just making a command line import tool. Run the command and it does its best to import everything. But telling Tanzawa how to map categories to streams would entail complex command parameters, which I wouldn't want to use myself, let alone inflict on others.

    Rather, I need a simple web interface and database tables that will let me manage and monitor the process. The basic workflow I'm imagining is something like this:

    1. User uploads Wordpress export file -> Tanzawa saves it into a blob in its database along with some basic meta information about it.
    2. Tanzawa will create a mapping record for each category/post/post-kind found in the file. In step 2 users will see a list of their Wordpress categories with a dropdown next to each one with the stream it should map to (not mapping is also an option).
    3. Tanzawa will also provision a record for each photo and post to import. This will include its planned final permanent url, as well  its existing permanent url, and will be central when rewriting content.
    4. The photo records will track not only urls, but also file download status, so we don't download photos twice. There should be a page where users can see a list of all photos to import, the status, and perhaps a button to retry if it's failed. 

    One tricky bit will be that Tanzawa doesn't support background tasks. Which means I can either introduce them (don't really want to) or I need to find a way to control entirely by the front-end.  I think a little a small Stimulus controller on the photo list page that loops through each photo and call an import api should be sufficient.

    5.  Once the photos have been imported there should be a big button to publish all the changes. This will be button that will actually execute the entry creations.
    6. After importing is complete, all of the old Wordpress urls should automatically redirect to their new Tanzawa permalink.

    Throughout this process I'll likely find data that I (should) import that I don't have a way to handle in Tanzawa - and as such I may need to create features to handle them along the way.

    Thinking about how large of a task importing Wordpress properly is a bit daunting. But if I just make a little progress each day, piece by piece, I'll complete it before I know it.
1 of 2 Next