...

I’ll try and make this short and sweet. I’m not trying to turn this into a recipe where you need to scroll through 20 screens of backstory just to figure out how much flour you need.

In fact. If you know what bookmarklets are, are using obsidian, and have some things stuck in Trello because it’s a pain to get stuff out, then just drag this link (Trello –> Obsidian) to your browser bookmarks and go to town. You’ll probably figure it out. If that’s not enough, jump to how to use it and ignore all the beautiful time I lost to padding out the rest of this post.

Otherwise, here’s 20 screens of backstory.

Why obsidian?

I’ve been an avid user of Obsidian (A second brain, for you, forever. As their tagline says.) for a couple years. There are few apps that have ever affected my productivity as much as obsidian has. I’m not going to go into detail about how it helps me to better organize and connect everything that I’ve ever written, or how it has created a better system for maintaining and helping me act on tasks and projects because there’s a lot of coverage on the internet for those sorts of things. In fact, here are a few:

What’s a boookmarklet, you ask?

Remember the time before Chrome Extensions existed? If you just asked me what a bookmarklet is, then you clearly don’t. I get it, I might be old.

Before browser extensions, the best we had were bookmarklets - bookmarks that contained a bunch of JavaScript code that could run on any page. They didn’t need to be installed, they didn’t ask for crazy permissions, and they didn’t run all the time collecting data on every page you visited.

They still don’t. And I think they still have a place in the modern web.

I vented about this a little bit recently when I wrote a bookmarklet for copying YouTube links with specific timecodes in markdown so I could use them in Obsidian.

The following chart shows Google search trends for “Bookmarklet” over the last 5 years and their down-trend following the launch of Chrome Extensions.

...
A chart showing search trends for "Bookmarklet" over time.
Source: Google Trends United States 01 Jan 04 - 01 Apr 23

What’s that bit of uptick at the end? Maybe we are on the verge of a resurgence and that people are starting to realize they don’t need a Pinterest Extension or a collection of useless tools mucking up their browser UI just to quickly add quirky DIY projects to your future dream home projects - especially with many extensions overstepping their usefulness.

Are bookmarklets safe? Specifically this one?

I’m glad you’re asking these questions. You should be. Again, smarter people something something:

As for what exactly this bookmarklet is doing, you’ll just have to look at the code to find out. Spoiler alert, its doesn’t do anything other than pull stuff off of the page and copy it into your clipboard. So yeah, it’s safe. The bookmarklet’s code is actually minified, so here’s the full source…

The code

I don’t feel like I need to explain code as long as it’s well commented. Contrary to what this article implies, I don’t write code - which you’ll clearly see if you actually look through this.

// The variable that will store all the text, starts with the kanban board settings
var obsidianText = "---\n\nkanban-plugin: basic\n\n---\n\n";

// Something to keep track of just to display when it's copied.
var numberOfLists;
var numberOfCards;

// Get all the lists in trello
var trelloLists = document.getElementsByClassName("js-list");
numberOfLists = trelloLists.length;

// Cycle through all the lists
for (l = 0; l < numberOfLists; l++){
  // Get the list name
  var trelloListHeader = trelloLists[l].getElementsByTagName("h2")[0].innerText;

  // Append the header to obsidianText in markdown
  obsidianText += "\n## " + trelloListHeader + "\n";

  // Get all the cards in each list
  var trelloItems = trelloLists[l].getElementsByClassName("list-card");
  numberOfCards = numberOfCards + trelloItems.length;

  // Cycle through all the cards in each list
  for (i = 0; i < trelloItems.length; i++){

    // Get the card title
    var trelloItemTitle = trelloItems[i].getElementsByClassName("list-card-title")[0].innerText;

    // Grab all of the labels if they have text specified. This does not get labels that are just colors.
    var trelloLabels = trelloItems[i].getElementsByTagName("button");

    // cycle though all of labels
    for (b=0; b<trelloLabels.length; b++){
      var ariaLabel = trelloLabels[b].getAttribute("aria-label"); // aria label is formatted as aria-label = "Color:red title: "Label_Text""
      var splitAriaValue = ariaLabel.split('title: ')[1]; // Split the string to just get the title, so 0 is trash 1 is the value of 'title' “Label_Text”"

      splitAriaValue = splitAriaValue.replace("“", "") // get rid of the smart quotes
      splitAriaValue = splitAriaValue.replace("”", "") // both of them

      // Append the label to item
      if (splitAriaValue != "none"){
        trelloItemTitle = trelloItemTitle + " #" + splitAriaValue;
      }
    }

    // Get the date. We can't get the time because trello doesn't display it in the list.
    var trelloDate = trelloItems[i].getElementsByClassName("js-due-date-text");
    if (trelloDate.length > 0){ // Only work on the ones that have a date.
      trelloDate = trelloDate[0].innerText;
      var trelloConvertedDate = new Date(trelloDate).toISOString().substring(0, 10);; // Convert it to an actual date so we can change the format
      // Append the date to item
      trelloItemTitle = trelloItemTitle + " @{" + trelloConvertedDate + "}";
    }

  // Append the item (with labels and date) to obsidianText in markdown
  obsidianText += "- [ ] " + trelloItemTitle + "\n";
  }
}

// Append the final expected kanban settins
obsidianText += '\n\n%% kanban:settings\n```\n{"kanban-plugin":"basic"}\n```\n%%';

//Copy text to the clipboard
navigator.clipboard.writeText(obsidianText);


// Flash the time on the page in an overlay so that I know I clicked it.
var elemDiv = document.createElement('div');
elemDiv.innerHTML = "<h1 style='font-size:40px; color:white; text-align:center; margin-top:2em;'>" + "Copied " + numberOfLists + " Lists and " + numberOfCards + " cards. </h1>";
elemDiv.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;top:0';
document.body.appendChild(elemDiv);

// Have it fade out after a bit
setTimeout(function(){ elemDiv.style.display = "none"; }, 2000);

The minified code

var numberOfLists,numberOfCards,obsidianText="---\n\nkanban-plugin: basic\n\n---\n\n",trelloLists=document.getElementsByClassName("js-list");for(numberOfLists=trelloLists.length,l=0;l<numberOfLists;l++){var trelloListHeader=trelloLists[l].getElementsByTagName("h2")[0].innerText;obsidianText+="\n## "+trelloListHeader+"\n";var trelloItems=trelloLists[l].getElementsByClassName("list-card");for(numberOfCards+=trelloItems.length,i=0;i<trelloItems.length;i++){var trelloItemTitle=trelloItems[i].getElementsByClassName("list-card-title")[0].innerText,trelloLabels=trelloItems[i].getElementsByTagName("button");for(b=0;b<trelloLabels.length;b++){var ariaLabel=trelloLabels[b].getAttribute("aria-label"),splitAriaValue=ariaLabel.split("title: ")[1];"none"!=(splitAriaValue=(splitAriaValue=splitAriaValue.replace("“","")).replace("”",""))&&(trelloItemTitle=trelloItemTitle+" #"+splitAriaValue)}var trelloDate=trelloItems[i].getElementsByClassName("js-due-date-text");if(trelloDate.length>0){trelloDate=trelloDate[0].innerText;var trelloConvertedDate=new Date(trelloDate).toISOString().substring(0,10);trelloItemTitle=trelloItemTitle+" @{"+trelloConvertedDate+"}"}obsidianText+="- [ ] "+trelloItemTitle+"\n"}}obsidianText+=&#39;\n\n%% kanban:settings\n```\n{"kanban-plugin":"basic"}\n```\n%%&#39;,navigator.clipboard.writeText(obsidianText);var elemDiv=document.createElement("div");elemDiv.innerHTML="<h1 style=&#39;font-size:40px; color:white; text-align:center; margin-top:2em;&#39;>Copied "+numberOfLists+" Lists and "+numberOfCards+" cards. </h1>",elemDiv.style.cssText="position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;top:0",document.body.appendChild(elemDiv),setTimeout((function(){elemDiv.style.display="none"}),2e3);

How to use it

Finally, we made it through all the backstory. As promised here’s what to do with this bookmarklet, if you couldn’t figure it out.

Trello –> Obsidian

  1. Drag the link above to your browser bookmarks. It’s a bookmark, but the url is actually just JavaScript. That JavaScript will run on any page when you click it.
  2. Rename it if you feel like it
  3. Go to a board in Trello and click the bookmark. It will tell you how many lists and cards, in total, that it copied. If something doesn’t happen… no idea.
  4. Open a new note in Obsidian and make sure to view the note in source mode. I can’t stress that enough. If you copy it in some other way, it’s bound to mangle the text you’re pasting in.
  5. Flip over to the Kanban View (open up your Command Pallet and Toggle Kanban View)
  6. Enjoy

If reading isn’t your style, here’s me giving a quick overview of how to use it:

Limitations and constraints

  • This bookmarklet won’t grab any description or any attached files that are in your Trello cards. Just the card name, the named labels and a due date.
  • If your Trello labels aren’t titled (they’re just a color) - this will ignore them. Go in and name all your labels if you want them to be brought over.
  • Obsidian’s kanban boards let you specify a time, Trello does not.

Thanks

If you made it here, as always, thanks for stopping by.

in coding javascript productivity

I came across a post the other day where someone was surprised that you could put JavaScript into a bookmark and run it from on any page. They even asked what to call that type of thing. I was surprised. They’re called bookmarklets and they’ve saved me on numerous occasions.

For all you folks that don’t know, before the invention of chrome extensions and browser plugins, we used to cram JavaScript into browser bookmarks so that we could do things with the pages we were using. Years ago, I made a bookmarklet for copying tweets so that they could be embedded into my own blog — long before Twitter came up with embeddable tweets.

We don’t always need a massive permission grabbing chrome extension to add some extensibility to a page. Today I’m going to show you how I made one just last weekend to scratch an itch I’d been having. If you know a bit of JavaScript, you can come up with some pretty clever ways of interacting with the code on other people’s pages.

Taking notes on YouTube videos

I played around with Memetic for taking notes on YouTube videos but I always just ended up exporting those notes into Obsidian (my second brain) and I figured I could streamline the process. The most useful feature in Memetic was adding the timestamp (and link) to the notes I was taking.

Going from Memetic and into something more useful, like Obsidian, seemed like an unnecessary step when I would normally just take all my notes in Obsidian in the first place.

I needed to fix my process.

YouTube’s sharing URL

I figured that link would exist somewhere in the page on the video I was watching — I just needed to grab it and get it into obsidian. YouTube has a bit of UI that exposed that link, but I’m not opening that up, clicking a button, and copying it out every time. That does mean that information is in the code and I can work with that.

Youtube's Sharing modal showing icons for sharing to multiple networks including twitter, embedding, or email. It also shows the url value, an option for starting the video at specific time and copying the url to the clipboard
Youtube's sharing modal with an option to start at the current time of the video.

The Plan for the bookmarklet

What did I need this thing to do?

  1. Get the URL out of the Youtube video page
  2. Format it as markdown
  3. Copy it to the clipboard (So I can paste it in Obsidian quickly)

The code

I don’t feel like I need to explain code as long as it’s well commented:

// Function to convert number of seconds into Hours::Minutes::Seconds
function minutesSeconds(s){
	return(s-(s%=60))/60+(9<s?':':':0')+s;
}

// The Main Function
function start(){
	// Current Page
	var currentURL = window.location.href;

	// Where the data is in youtube
	var bar = document.getElementsByClassName("ytp-progress-bar")[0];

	//Converting that to data
	var seconds = bar.getAttribute("aria-valuenow");
	var secondsInMS = minutesSeconds(seconds);

	//Adding the time to the url
	var URL = currentURL + "?t=" + seconds;

	//Setting up the markdown format : [This is the linkname](link.html)
	var obsidianFormat = "[" + secondsInMS + "]" + "(" + URL + ")";

	// Put the obsidian formatted link into the clipboard
	navigator.clipboard.writeText(obsidianFormat);
	null;

	// Flash the time on the page in an overlay so that I know I clicked it.
	var elemDiv = document.createElement('div');
	elemDiv.innerHTML = "<h1 style='font-size:100px; color:white; text-align:center; margin-top:2em;'>" + secondsInMS + "</h1>";
	elemDiv.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;';
	document.body.appendChild(elemDiv);

	// Have it fade out after a bit
	setTimeout(function(){ elemDiv.style.display = "none"; }, 600);
}

// Start
start();

The minified code for the bookmarklet

javascript:function minutesSeconds(s){return(s-(s%=60))/60+(9<s?':':':0')+s}function start(){var currentURL=window.location.href;var bar=document.getElementsByClassName("ytp-progress-bar")[0];var seconds=bar.getAttribute("aria-valuenow");var secondsInMS=minutesSeconds(seconds);var URL=currentURL+"?t="+seconds;var obsidianFormat="["+secondsInMS+"]("+URL+")";navigator.clipboard.writeText(obsidianFormat);null;var elemDiv=document.createElement('div');elemDiv.innerHTML="<h1 style='font-size:100px; color:white; text-align:center; margin-top:2em;'>"+secondsInMS+"</h1>";elemDiv.style.cssText='position:absolute;width:100%;height:100%;opacity:0.8;z-index:1000;background:#000;';document.body.appendChild(elemDiv);setTimeout(function(){elemDiv.style.display="none"},600)}start();

If I wasn’t so lazy…

Things I could do to improve this:

  • Instead of hitting the bookmarklet every time, I could have injected a button into the page that I could hit every time, but I’m cool with the simplicity of this.
  • Make it work with Vimeo. I tend to watch videos on there too sometimes, but rarely. Maybe next time I need to take notes on one that’s not private.
  • This only works on Youtube.com, not when it’s embedded in a page somewhere else. That could potentially be helpful.

in coding javascript productivity

When I got word that the FDA had approved and were starting to distribute the COVID-19 vaccine, I should have been a little happier about it - people are dying, struggling to pay their bills, and/or dealing with mental health.

I hope this vaccine will help prevent the deaths of more people and will get businesses (especially small ones) back up and running. I do.

But, selfishly, I was a bit disappointed that I have to think about transitioning back into a routine that includes going back into an office every day (or more than I am now). I love my coworkers and I love the work that we do, but I’ve had a lot of time to reflect on how remote work has complexly changed the way we work and interact with each other - and it has been almost all for the better.

I’m not going to go fully into the details here, but there are several things that I’m going to have a hard time adjusting to when going back into the office.

The amount of distractions

A time-lapsed photo of several dozen people walking up and down stairs. Its a bit blurry.
This is mentally how it feels working in an open office.

I work in an open office environment, which means that most days that I’m not sitting through meetings I will sit at my desk with headphones on trying to block out all the disruptions that happen during the day. Sometimes I do it to myself - I’ll hear a coworker talking about a project and want to chime in. Other times, people will ignore the fact that I have headphones on and walk up to my desk and knock on it like it’s a front door. I’m guilty of doing the same thing to people.

I’m much less distracted at home.

The ability to facilitate workshops

A close up of a large sheet of paper board with markers.
Ahh. Sticky notes, markers, and oversized sheets of paper. That’s how you know ideas are being created.

Quickly into transitioning to remote work I adopted Mural - an amazing app for holding remote facilitation sessions. Helping teams collaborate more efficiently and pull out new ideas is one of my favorite parts of what I do for a living.

Facilitation complexly online has had some benefits that I didn’t see during in-person sessions. For instance, I was doing a workshop on goals and asked the participants to start writing out their goals onto sticky notes. One of the participants was coming up with some that were a little too broad.

In an in-person session, even though I would have walked around to help coach ideas out of everyone, I may not have noticed the need to step in until after we had started sharing the ideas with the larger group - not great if we’re trying to generate as many ideas as possible.

In the remote facilitation session, I was able to see each idea as they were created and was able to chime in quickly to help get that participant generating more detailed goals - adding more value to the workshop.

Facilitating remotely gives you a gods-eye-view that you just can’t match in-person.

Keeping up with documentation

Two very large stacks of papers side by side.
The last set of functional requirements that I had to make.

I loathe documentation. Or, at least, I thought I did. I never made meeting notes and assumed (because we are all grown-ups) that anyone that was given something to take away and work on, would do that without prompt (and they usually do).

Out of necessity with this new environment and the fact that I could type notes while attending meetings (I used to just bring a notebook and rarely ever revisited those notes in details), I’m consistently sending notes, keeping better track of my tasks, and thanks to our sessions now being on Mural, we have more of a written record of our collaboration than we’ve ever had before.

When I do go back in, I’m going to need to bring my laptop everywhere I go.

Diving into deep work

Looking down a cylindrical pit made of glass with offices on the other side.
You thought I was going to put a picture of someone diving here, didn’t you?

It is so important to have the time and space to think deeply about problems and to research new ideas, methods, and processes. During the last 9 months, I have been able to adopt a better system for managing my knowledge and to turn off the distractions that I would normally receive in the office.

I feel more productive than ever. I am doing my best work and I’m more inspired about the work that I’m doing than I ever have been.

Going back into the office, although armed with new techniques for managing chaos, will bring my levels of deep work back to nearly non-existent if I’m not careful. I’m not looking forward to that.

Dreading the transition back

Several magazines, a phone, and a coffee cup sitting on a couch cushion
This isn’t a bad setup for a remote work environment. Coffee, magazines and a hipster pillow — what else would you need?

I’m pretty sure I can convince my higher-ups to let me stay remote indefinitely, but I’m certain, as a team, we will never be as productive as we are right now. I think back to those meetings where just a couple of people are dialing in on a phone and how difficult it is collaborating when some part of the team is at home and some are in the office. The people at home often missed out on conversations whether that was because of the noise in conference rooms or missing out on impromptu meetings.

It just doesn’t work. That will leave us having to adopt remote-first collaboration even when in the office - connecting to video calls when another participant is sitting just 6 feet away.

I’m not sure how well that will go over culturally.

It’s hard not to see the value that this experience has brought. It looks like we’ll just have to look closer at how we can adapt what has worked for us once we go back in.

I can’t speak for the rest of my coworkers, but I can’t wait to do that from the comfort of my couch.

in business productivity

This is my obligatory coronavirus update.

I’ve been working from home due to the coronavirus, and yesterday my governer put NJ on lockdown. I think I’m on day 7 of socially distancing from the rest of you all. Although I’ve gone out quickly to pick up some supplies from the grocery stores, and yesterday drove around the city looking at how deserted it felt, I’ve pretty much stayed put. As an introvert, this isn’t a big adjustment for me. I’m not getting antsy to go anywhere and I’m not getting cabin fever. My kids have been handling it pretty well too - as homeschoolers, they’re used to online classes and not accidentally joining me on my conference calls to work (much hilarity has already ensued on several calls involving people’s kids).

With no idea of how long we’re going to be keeping this up, this is a great opportunity for getting some things accomplished that are hard to weave into my everyday routines. Although I have spent an unreasonable time deleting the emails from every single company that has ever gotten my email address updating me on how they are handling the outbreak, they have finally stopped coming. I was really wondering how my cat’s vet from 15 years ago was holding up during this.

Aside from the potential of getting sick, and continuing to read the same ’tips to working remotely’ article from every company in existence, there are several personal benefits of being on lockdown and I’m ready to put every minute of this time to relatively good use.

Let’s start with some of the benefits:

  1. No commute. I drive a lot. I have 1 hour and 30 min commute for me every day. So that’s 15 hours of my life I get back.
  2. Less eating out. It’s convenient, but you know what…I can make my own falafel or noodles. It’s not that hard.
  3. I get to hang out with my kids more. Maybe some people aren’t a fan of spending time with their families, but my kids aren’t going to be kids forever. I’m up for playing video games with my son, doing crafts with my daughter, playing board games and making movie night every night.
  4. I don’t have to, or want to, trim my beard. It’s been unwieldy long for some time now, on the verge of looking homeless. I stopped shaving for a reason, but at the time didn’t realize that it takes just as much work to keep it looking reasonably presentable as it does to keep it clean shaved. I’m about to embrace looking like a homeless dude.
  5. I don’t have to wear dumbass work clothes. Yeah, I don’t have to wear a tie or anything to work, but I’m real cool with just wearing pajamas all day.
  6. Working from home is setting a precedence for doing it more regularly. For a long time, I worked at home at least one day a week. It made up for my long commute to work, but at some point, the perception of working from home changed and I’ve been in the office every day for probably 5 or so years. Earlier this year, I jokingly told my boss that we needed to adopt a better policy and just go into the office 1 day a week. I hope it wasn’t me that jinxed this whole situation.
Bookshelf with a mug and a computer on it
My current workspace

So what’s the plan? Good question. I’m sure not going to the beach (what is wrong with you people?).

  1. Write and publish. When I was a young designer entering the field I made it a point to publish articles online pretty regularly. It was so long ago that some of the topics were around XLST (remember that?), why you shouldn’t use Flash (I wrote an article for SmashingMagazine.com) and how it would be so cool if I could get the internet on my phone (yeah that old). I feel like I have a good bit to say and I sure don’t like doing it in front of people, so blogging became my outlet. I’ve attempted to get back into it every few years but it’s a hard habit to create. I’m hoping I can make some strides here. At least I have a pile of half baked drafts sitting around to get me started.
  2. Make some art. I used to sit down in a single evening and crank out some piece of art - sometimes it was pen and paper, other times it was illustration with photography. It was so much fun. I guess my broad range of interests have been distracting me from doing it. Also motivation. My son is really big into creating animation, so I’m hoping some of that will rub off on me while I’m sitting next to him.
  3. Watch some movies. I’m notorious for never having seen movies. I don’t get a lot of references because I usually wait 10 years to watch really popular movies (The Matrix, Avatar) to avoid anything that’s culturally relevant. I thought a good place to start for catching up on movies would be the AFI Top 100 - it looks like I’ve seen maybe 10 or 11 of them previously. I’m going to start with the 1996 list from the bottom and work my way up. I’m going to try and keep up with sharing quick reviews. I can’t wait to see what’s been deemed the best movies from American cinema.
  4. Read even more. This is a constant goal of mine. I read maybe 25 books last year and the backlog of books that I want to read is in the hundreds. I’d like to knock out a dozen of those and I probably could if I just delete Reddit off my phone.
  5. Make more plans. I hope to build habits, connect with my kids, and push myself to accomplish more. Maybe see how I can adjust my life to be more focused on myself after the lockdown ends, you know that whole work/life balance that everyone talks about. Who knows, maybe it’s time to start a business or join a board of a nonprofit or think about teaching.

That’s what I’m doing during all this and if I do well with #1, you’ll be hearing much more from me. I"m curious to know what you all have planned.

Stay home and accomplish something.

in productivity

I graduated from college 15 years ago. Why did I decide to go back to school to pursue my masters in User Experience? I’m still solidifying that answer so I won’t be telling that story today.

Instead I’ve been asked by a professor to document some of my learning along the way. I wish this was required of me early on because it has been a very interesting and fun experience. I have worked on some incredibly cool projects and have worked with a number of other talented UX designers and researchers. So far it’s been worth it and there’s plenty of valuable insights I could share that I wish I had during the process. Oh well.

I have such little time to get my thoughts out and blog about them so these are going to be short and sweet. Maybe I’ll fill you in on what the last 6 months has been like but that’s going to take me some time.

in productivity