rockyourcode: How to Write Online Workshop, Making a Chrome Extension: How to Open Link in New Tab, Notes on ”How to Build a Career in Tech”, Twitter, Full Text RSS Feed for Hugo, How to Install Docker Compose v2 on Linux (2021), etc.
Hello 👋! Thanks for subscribing.
Here are the articles from last week:
Notes on “How to Write Online Workshop” by David Perell
Published on: 2021-06-21
tags: Lab, Notes, Writing
In this ~1 hour video David Perell explains his method for writing.
The Capture Habit
You need a note-taking system for generating better ideas.
What ideas should you save?
PILE:
- personal
- inspiring
- easily lost (losable)
- effective (useful)
Sources: ebooks, online articles – use a service like readwise.
Capture your ideas while you read.
Capture things while they are fresh.
Writing
Modern writing isn’t created. It’s assembled.
You have to cull your writing from vast amounts of notes.
Writing can be a collaborate progress. Ask for feedback.
The Content Triangle
image from Bronson Chang’s notes
conversations -> share -> feedback -> create content -> distribute
2-minute-drill: explain your idea in 2 minutes or less by talking. Humans are better at talking than reading. After that, you can distill the audio to write your article.
You don’t need to be 100% original.
Improve Your Writing
CLEAR sentences:
- Create a rhythm
- Link your sentences
- Eliminate anything that’s confusing
- Add colorful details
- Remove unnecessary words
Don’t just write words. Write music.
Sweet spot: words people know, but don’t say.
image from Bronson Chang’s notes
Telling a Story
Roller-Coaster: start with a setup (tension rises), conflict, resolution.
image from Bronson Chang’s notes
Learn to Write FAST
FAST Writing: write first, research second. Write in the course of your life.
- Find
- Assemble
- Speak
- Teach
Use your note-taking system, structure ideas by talking, record yourself, set a timer.
Audience
Grow your audience on public platforms. Build relationships on private ones.
- Create value on public platforms.
- Send audience to private platforms.
- store value with your email list.
Build a Personal Monopoly
Define your personal monopoly:
- specific (the more narrow the niche, the better)
- unusual (skills or knowledge not often found together)
- complementary (skills that reinforce and amplify each other)
- experimental (skills gained through experience).
Aim for niche fame.
Get going. Then get good.
Writing and Thinking
When writing is thinking, re-writing is re-thinking.
When you put words on paper, you free up you mind which allows you to see things that you didn’t realize before.
When you write, you give yourself opportunity to go over ideas over and over again.
Imposter Syndrome
You are an imposter, because you are trying to do things out of your comfort zone.
But everyone is an imposter. David Perell didn’t know how to run a writing school before he tried. Jeff Bezos didn’t know how to run a trillion-dollar business like Amazon.
When you realize that everybody is an imposter, you realize that nobody is an imposter.
You have an obligation to share your ideas. This is how our society advances.
Links
Making a Chrome Extension: How to Open Link in New Tab
Published on: 2021-06-20
tags: JavaScript
Last year I created a Chrome extension that opens a new Picture in Picture window. With the extension, I can see my browser (or a different window) in a small window in a different application.
I want to open the extension in a new tab.
Here’s how to do that.
You’ll need a manifest.json
file with the following content:
{
"manifest_version": 2,
"name": "Picture in Picture",
"description": "This extension will open a new tab for Picture in Picture mode",
"version": "1.0",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_icon": "camera.png"
},
"icons": {
"64": "camera.png"
},
"permissions": ["tabs"]
}
Please note the permissions
and the background
keys.
background.js
contains one function:
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.create({
url: chrome.extension.getURL('index.html'),
selected: true,
})
})
That means that the extension will open the index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Picture In Picture</title>
</head>
<body>
<!-- your html code -->
<script src="./index.js"></script> <!-- index.js contains the main logic -->
</body>
</html>
You can see the complete code on GitHub.
Links
Notes on ”How to Build a Career in Tech”
Published on: 2021-06-19
tags: Lab, Notes
Kurt Kemple is a self-taught programmer who learned to code when incarcerated. In his talk with Jason Lengstorf he shares his experiences.
Here are my notes from the ~1 hour video:
Technical skills are a small part of your day to day job. Kurt learned how to prioritize, commmunicate with others and how to organize the work from his previous experience in construction work and as a line cook. Break a big task into small pieces.
Empathy and understanding: “Your perspective of the world is not the center of everything, it’s not the default. Lots of people have experiences that are different from yours.”
Know the stakeholders. Understand what they are invested in.
How to learn? Kurt learns best by doing. He breaks new skills into manageable chunks, and practices them step by step.
How to break into tech: Until you have your first role, you need something for your resume — either certificates or a great portfolio. You also want to highlight the skills you want to get hired for.
One of the best ways to break into tech is to build a community. Learn in public.
Often, job opportunities come from your network.
Resume tips:
- two column layout (1 page): on the top left the most important info, below that the most important experience (certificate, a project), on the right side put the second most important info
- make different resumes for different jobs
Remote work: traditionally, the advice for junior developers was to aim for an on-site job, but that’s not possible due to the pandemic.
Ideally, your future company either has a track record for remote work or already on-boarded junior developers.
Find the people in your job that are happy to answer your questions, and ask them — a lot. Communicate early, communicate often. Optimize for feedback.
Focus on the whys, not hows. Everyone can pick up the newest and hottest tech stack and learn how to use it. Rather aim to understand why to use a technology.
Jason Lengstorf, the interviewer, also explains that he doesn’t expect juniors to know a lot, but he wants to get the sense that the junior can find out (“self-starter”). Be confident in yourself, be confident in your ability to learn and grow.
Be aware of burnout. Don’t start a new job and deliver 110%. This becomes your baseline, and soon you’ll be expected to clock in 130%.
If possible, dedicate 70-80% to productivity on the job, and around 20-30% to learning and growing.
How do you learn to program when you don’t know enough about computers?
Try to get a basic understanding of how computers and the internet work, how to use the keyboard effectively. If you don’t know anything about computers, you’re trying to learn two things at once.
Links
Twitter Tip: Tokimeki Unfollow
Published on: 2021-06-18
tags: Tools
Twitter shines when you have an engaging Twitter homepage. The more interesting the accounts you follow, the more interesting your Twitter feed.
My Twitter account is more than 10 years old, and I decided to prune it.
Tokimeki Unfollow is a cute and free online tool. The web application allows you to comb through your accounts to see if they are still relevant to you.
Tokimeki Unfollow uses the “Konmari” method, where you ask yourself if an account still “sparks joy”.
Give it a try!
Links
- Tokimeki Unfollow by Julius Tarng
TIL: How to Create Full Text RSS Feed for Hugo
Published on: 2021-06-17
tags: TIL, Hugo
Who wants to read an incomplete RSS feed that forces you to open the original website?
Hugo is the static site generator that powers my blog.
Hugo ships with a default RSS template which only shows a summary of your articles.
If you want to read the full content, you’ll need to visit the website. That sucks.
I want to create a full-text RSS feed for my blog.
Template Lookup Order
We’ll need to create a modified RSS template. Let’s make sure that Hugo will use the new one instead of the default template that comes with Hugo or the Hugo theme.
I created a new directory (layouts
) in my Hugo folder (the root folder, which also contains my config.toml
file).
Let’s copy the default Hugo RSS template into a file called index.xml
(layouts/index.xml
). That’s on position 5 in the template lookup order and higher than the default template.
Create New RSS Template
</span><span class="o">-</span> <span class="err">$</span><span class="nx">pctx</span> <span class="o">:=</span> <span class="p">.</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="k">if</span> <span class="p">.</span><span class="nx">IsHome</span> <span class="o">-</span><span class="p"></span> <span class="err">$</span><span class="nx">pctx</span> <span class="p">=</span> <span class="p">.</span><span class="nx">Site</span> <span class="p"></span><span class="o">-</span> <span class="nx">end</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="err">$</span><span class="nx">pages</span> <span class="o">:=</span> <span class="nx">slice</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="k">if</span> <span class="nx">or</span> <span class="err">$</span><span class="p">.</span><span class="nx">IsHome</span> <span class="err">$</span><span class="p">.</span><span class="nx">IsSection</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="err">$</span><span class="nx">pages</span> <span class="p">=</span> <span class="err">$</span><span class="nx">pctx</span><span class="p">.</span><span class="nx">RegularPages</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="k">else</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="err">$</span><span class="nx">pages</span> <span class="p">=</span> <span class="err">$</span><span class="nx">pctx</span><span class="p">.</span><span class="nx">Pages</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="nx">end</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="err">$</span><span class="nx">limit</span> <span class="o">:=</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Config</span><span class="p">.</span><span class="nx">Services</span><span class="p">.</span><span class="nx">RSS</span><span class="p">.</span><span class="nx">Limit</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="k">if</span> <span class="nx">ge</span> <span class="err">$</span><span class="nx">limit</span> <span class="mi">1</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="err">$</span><span class="nx">pages</span> <span class="p">=</span> <span class="err">$</span><span class="nx">pages</span> <span class="p">|</span> <span class="nx">first</span> <span class="err">$</span><span class="nx">limit</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="nx">end</span> <span class="o">-</span><span class="p">
</span><span class="o">-</span> <span class="nx">printf</span> <span class="s">"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>"</span> <span class="p">|</span> <span class="nx">safeHTML</span> <span class="p">
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title></span> <span class="k">if</span> <span class="nx">eq</span> <span class="p">.</span><span class="nx">Title</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Title</span> <span class="p"></span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Title</span> <span class="p"></span> <span class="k">else</span> <span class="p"></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Title</span> <span class="p"> on </span> <span class="nx">end</span> <span class="p"></span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Title</span> <span class="p"></span> <span class="nx">end</span> <span class="p"></title>
<link/></span> <span class="p">.</span><span class="nx">Permalink</span> <span class="p">
<description>Recent content </span> <span class="k">if</span> <span class="nx">ne</span> <span class="p">.</span><span class="nx">Title</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Title</span> <span class="p"></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Title</span> <span class="p">in </span> <span class="nx">end</span> <span class="p"></span> <span class="nx">end</span> <span class="p">on </span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Title</span> <span class="p"></description>
<generator>Hugo -- gohugo.io</generator></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">LanguageCode</span> <span class="p">
<language></language></span><span class="nx">end</span><span class="p"></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">email</span> <span class="p">
<managingeditor></span> <span class="nx">with</span> <span class="err">$</span><span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">name</span> <span class="p"> ()</span><span class="nx">end</span><span class="p"></managingeditor></span><span class="nx">end</span><span class="p"></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">email</span> <span class="p">
<webmaster></span> <span class="nx">with</span> <span class="err">$</span><span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">name</span> <span class="p"> ()</span><span class="nx">end</span><span class="p"></webmaster></span><span class="nx">end</span><span class="p"></span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Copyright</span> <span class="p">
<copyright></copyright></span><span class="nx">end</span><span class="p"></span> <span class="k">if</span> <span class="nx">not</span> <span class="p">.</span><span class="nx">Date</span><span class="p">.</span><span class="nx">IsZero</span> <span class="p">
<lastbuilddate></span> <span class="p">.</span><span class="nx">Date</span><span class="p">.</span><span class="nx">Format</span> <span class="s">"Mon, 02 Jan 2006 15:04:05 -0700"</span> <span class="p">|</span> <span class="nx">safeHTML</span> <span class="p"></lastbuilddate></span> <span class="nx">end</span> <span class="p">
</span><span class="o">-</span> <span class="nx">with</span> <span class="p">.</span><span class="nx">OutputFormats</span><span class="p">.</span><span class="nx">Get</span> <span class="s">"RSS"</span> <span class="o">-</span><span class="p">
</span> <span class="nx">printf</span> <span class="s">"<atom:link href="</span><span class="o">%</span><span class="nx">q</span><span class="s">" rel='\"self\"' type="</span><span class="o">%</span><span class="nx">q</span><span class="s">"></atom:link>"</span> <span class="p">.</span><span class="nx">Permalink</span> <span class="p">.</span><span class="nx">MediaType</span> <span class="p">|</span> <span class="nx">safeHTML</span> <span class="p">
</span><span class="o">-</span> <span class="nx">end</span> <span class="o">-</span><span class="p">
</span> <span class="k">range</span> <span class="err">$</span><span class="nx">pages</span> <span class="p">
<item>
<title></span> <span class="p">.</span><span class="nx">Title</span> <span class="p"></title>
<link/></span> <span class="p">.</span><span class="nx">Permalink</span> <span class="p">
<pubdate></span> <span class="p">.</span><span class="nx">Date</span><span class="p">.</span><span class="nx">Format</span> <span class="s">"Mon, 02 Jan 2006 15:04:05 -0700"</span> <span class="p">|</span> <span class="nx">safeHTML</span> <span class="p"></pubdate>
</span> <span class="nx">with</span> <span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">email</span> <span class="p"><author></span> <span class="nx">with</span> <span class="err">$</span><span class="p">.</span><span class="nx">Site</span><span class="p">.</span><span class="nx">Author</span><span class="p">.</span><span class="nx">name</span> <span class="p"> ()</span><span class="nx">end</span><span class="p"></author></span><span class="nx">end</span><span class="p">
<guid></span> <span class="p">.</span><span class="nx">Permalink</span> <span class="p"></guid>
<description></span> <span class="p">.</span><span class="nx">Summary</span> <span class="p">|</span> <span class="nx">html</span> <span class="p"></description>
</item>
</span> <span class="nx">end</span> <span class="p">
</channel>
</rss>
The trick lies in changing the content of the XML <description>
tag.
The RSS 2.0 spec says that the description element can contain “the item’s full content or a summary of its contents, a decision entirely at the discretion of the publisher.”
Currently, we only show a short summary:
<description></span> <span class="p">.</span><span class="nx">Summary</span> <span class="p">|</span> <span class="nx">html</span> <span class="p"></description>
Change the line to the following:
<description></span> <span class="p">.</span><span class="nx">Content</span> <span class="p">|</span> <span class="nx">html</span> <span class="p"></description>
Bonus Tip: RSS Feed Limit
Hugo builds a RSS feed from the complete article backlog. You might want to restrict the number of RSS entries if you have many blog posts.
You need to add the rssLimit
field.
Example config.toml
:
baseurl = "https://www.rockyourcode.com"
languageCode = "en-us"
rssLimit = 25
Links
How to Install Docker Compose v2 on Linux (2021)
Published on: 2021-06-16
tags: Unix, DevTools, DevOps, Docker
In the video Docker Compose v2: What’s New in 2021: DevOps and Docker Live Show (Ep 126) Bret Fisher introduces compose v2.
compose is an instrument for running multiple docker containers on your local machine. I use it often to spin up a database container and a separate application container.
compose v2, a plugin for docker, is written from the ground up in Go and integrates better with existing tools.
The CLI is a drop-in replacement for the previous Python program docker-compose. The Python version is much slower than the new Go version.
If you want to use compose v2 on your Linux machine, you have to install it manually.
Install Compose V2 on Linux
Find the latest release with the v2
tag. Currently, that’s v2.0.0-beta.3
.
(I’m using amd64, if you’re using the new Mac M1, you’ll need to find the release for the arm architecture.)
Now type the following commands into your terminal):
# create the docker plugins directory if it doesn't exist yet
mkdir -p ~/.docker/cli-plugins
# download the CLI into the plugins directory
curl -sSL https://github.com/docker/compose-cli/releases/download/v2.0.0-beta.3/docker-compose-linux-amd64 -o ~/.docker/cli-plugins/docker-compose
# make the CLI executable
chmod +x ~/.docker/cli-plugins/docker-compose
The tool should work:
docker compose version
> Docker Compose version 2.0.0-beta.3
Learn more about compose v2 in this video:
Links
- Docker Compose v2: What’s New in 2021: DevOps and Docker Live Show (Ep 126)
- GitHub Docker Compose-CLI
- GitHub: Encountered problem with Linux installation script #1781 with solution by Eric Landry
Notes on “Hack Your Career”
Published on: 2021-06-15
tags: Lab, Notes
Troy Hunt talks about his journey from a corporate software job to independence in Hack Your Career (58 min video).
Troy is probably best known for the platform have i been pwned?.
One of the best ways to make yourself more marketable as a software developer is have an active online profile
What opportunities are you going to make for yourself?
Start a blog.
If you are willing to put yourself out there (writing online), you get valuable feedback from others. It’s documentation for you and others.
You don’t have to have a goal or a niche. You start.
Next step: speaking. Great exposure, you will be outside your comfort zone.
Start a podcast, start a user group, hold workshops. Use StackOverflow.
You will offend somebody.
If you’re not upsetting someone, you’re not trying hard enough!
But you will also make connections with others.
Your social media profile is your opportunity to demonstrate your character.
Tech staff is a cost factor. Future-proof yourself by showing your value (online) before you get fired.
Links
- Hack Your Career - Troy Hunt
- Don’t Call Yourself A Programmer, And Other Career Advice by Patrick McKenzie
Thank you for reading my blog.