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.
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:
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.
- not have any bugs
- be easy to use
- have proper documentation for getting started
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.
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.
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.
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.
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.
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 :)
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.
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.
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.
This past week was spent rounding out support for checkins.
I was so focused on getting locations functioning and out the door that forgot to include microformatted data. I've now included it along with the map and added tests to ensure I don't break it in the future.
Building locations helped me figure out the best pattern for adding 1-to-1 related data to an entry. A checkin is a location and a checkin record which is the name of the venue and a url for the venue. The one limitation I built in surrounding checkins is that they must be created via a micropub request and can only be updated via the admin interface.
While it's possible to integrate with Foursquare's places api and allow people to "checkin" using Tanzawa, it's a much better experience to use Swarm app and backfeed it.
Syndications is different from locations or checkins because rather than being a 1-to1 relationship, they're a 1-to-Many relationship. i.e. a single entry can have multiple syndication urls.
Supporting multiple syndication urls from micropub is straight forward, I can just iterate over the urls and save. However, the admin interface allows me to add, update, and delete records. In addition to the form itself, it also requires a (hidden) management form to manage the number of records and so forth.
Thankfully I was able to work the pattern out so going forward, adding any other 1-toMany data for a post should be much quicker.
Along with my regular status posts, I'm going to try to make a weekly roundup post for Tanzawa. As this is more of an experiment at this time, I'm putting them in the "Articles", but I may add a weekly stream just for these posts.
I build and launched the ability to associate a location with an entry. Initially I had planned on limiting locations to check ins and statuses, but decided against building in an artificial limitation.
Location support is baked into the Tanzawa micropub endpoint as well as the RSS feeds. Posts that have a location associated with them will display the location after the author's name in the posts' byline. RSS feeds will append the location name ( or coordinates where there isn't an address) to the end of the post.
While adding the map to the public post views, I also I did some cleanup. I had originally planned on having a 3 column layout for Tanzawa: left navigation, middle content, right meta. But having it split into 3 columns felt unnatural. I removed the meta-data from the third column, though it still exists.
I also cleaned up the footer so it's stuck of the page without extending the view port beyond the natural max. Practically speaking it means that you'd always get a scrollbar even if the content length didn't warrant it. Ironic given that the footer text reads "Made with care". This text is also now styled to reduce emphasis.
Posts that belong to multiple streams will have their streams highlighted on the left. There's also a new "Home" link that takes you to the top of the site.
1 of 2 Next