or

Top 5 Best Internet Live Support Extension To Increase Customers Interactions

Creative interactions call for creative measures - numerous extensions reduce, minimize or dilute the frustration of the customers and resolve issues quickly without the customer support team need....




or

How To Restore Hard Drive From A Time Machine + Other Ways

Have you chosen Mac for its reliable system? They really have a lot of advantages and are of the best quality. Mac users don’t face serious problems with hard drives often. But the reality is such...




or

6 Ways To Step Up Your Instagram Stories Game

Instagram Stories are an integral part of the platform. Though Instagram copied Snapchat’s concept a few years ago, over 500 million accounts use the Stories feature on a daily basis. Some users...




or

Why Choosing The Best Web Hosting Is Crucial For Your Business

Not many business owners think about hosting when building a new website for their business. But failing to choose the right web hosting can have a great impact on your website and, of course, your...




or

5 Tips For Doing A Fantastic Graphic Project

You’ve probably had the experience of browsing other people’s graphic projects and wishing you could achieve such effects too. In order to accomplish that, you should expand your knowledge by...




or

How To Create A Trustworthy Brand

The variables that determine business success are continually evolving. More than ever, customers want to be able to trust businesses with which they are transacting business. This involves building...




or

Creative Marketing Strategies For Law Firms To Engage With Potential Clients

The success of any organization strongly depends on the marketing strategies they use to reach their potential customers. Law firms are no exception since they also operate in a competitive field...




or

Where To Find Some Papers For Sale

If you look for a place to find academic papers for sale, you should know that there are lots of writing services on the Internet. But your task is to find a reliable online resource that would offer...




or

To Love What Is: A Marriage Transformed

I wish I had found Alix Kates Shulman’s memoir "To Love What Is: A Marriage Transformed" in the first month of my husband’s severe TBI, and yet I may not have absorbed it the way I did reading it fifteen years post-injury.







or

✚ Tornado Lines – Useful or Not? (The Process 088)

It looks like a tornado. It's messy. It's circular. It almost looks intentionally confusing. But how bad is it really?

Tags: ,




or

Markdown Comes Alive! Part 1, Basic Editor

In my last post, I covered what LiveView is at a high level. In this series, we’re going to dive deeper and implement a LiveView powered Markdown editor called Frampton. This series assumes you have some familiarity with Phoenix and Elixir, including having them set up locally. Check out Elizabeth’s three-part series on getting started with Phoenix for a refresher.

This series has a companion repository published on GitHub. Get started by cloning it down and switching to the starter branch. You can see the completed application on master. Our goal today is to make a Markdown editor, which allows a user to enter Markdown text on a page and see it rendered as HTML next to it in real-time. We’ll make use of LiveView for the interaction and the Earmark package for rendering Markdown. The starter branch provides some styles and installs LiveView.

Rendering Markdown

Let’s set aside the LiveView portion and start with our data structures and the functions that operate on them. To begin, a Post will have a body, which holds the rendered HTML string, and title. A string of markdown can be turned into HTML by calling Post.render(post, markdown). I think that just about covers it!

First, let’s define our struct in lib/frampton/post.ex:

defmodule Frampton.Post do
  defstruct body: "", title: ""

  def render(%__MODULE{} = post, markdown) do
    # Fill me in!
  end
end

Now the failing test (in test/frampton/post_test.exs):

describe "render/2" do
  test "returns our post with the body set" do
    markdown = "# Hello world!"                                                                                                                 
    assert Post.render(%Post{}, markdown) == {:ok, %Post{body: "<h1>Hello World</h1>
"}}
  end
end

Our render method will just be a wrapper around Earmark.as_html!/2 that puts the result into the body of the post. Add {:earmark, "~> 1.4.3"} to your deps in mix.exs, run mix deps.get and fill out render function:

def render(%__MODULE{} = post, markdown) do
  html = Earmark.as_html!(markdown)
  {:ok, Map.put(post, :body, html)}
end

Our test should now pass, and we can render posts! [Note: we’re using the as_html! method, which prints error messages instead of passing them back to the user. A smarter version of this would handle any errors and show them to the user. I leave that as an exercise for the reader…] Time to play around with this in an IEx prompt (run iex -S mix in your terminal):

iex(1)> alias Frampton.Post
Frampton.Post
iex(2)> post = %Post{}
%Frampton.Post{body: "", title: ""}
iex(3)> {:ok, updated_post} = Post.render(post, "# Hello world!")
{:ok, %Frampton.Post{body: "<h1>Hello world!</h1>
", title: ""}}
iex(4)> updated_post
%Frampton.Post{body: "<h1>Hello world!</h1>
", title: ""}

Great! That’s exactly what we’d expect. You can find the final code for this in the render_post branch.

LiveView Editor

Now for the fun part: Editing this live!

First, we’ll need a route for the editor to live at: /editor sounds good to me. LiveViews can be rendered from a controller, or directly in the router. We don’t have any initial state, so let's go straight from a router.

First, let's put up a minimal test. In test/frampton_web/live/editor_live_test.exs:

defmodule FramptonWeb.EditorLiveTest do
  use FramptonWeb.ConnCase
  import Phoenix.LiveViewTest

  test "the editor renders" do
    conn = get(build_conn(), "/editor")
    assert html_response(conn, 200) =~ "data-test="editor""
  end
end

This test doesn’t do much yet, but notice that it isn’t live view specific. Our first render is just the same as any other controller test we’d write. The page’s content is there right from the beginning, without the need to parse JavaScript or make API calls back to the server. Nice.

To make that test pass, add a route to lib/frampton_web/router.ex. First, we import the LiveView code, then we render our Editor:

import Phoenix.LiveView.Router
# … Code skipped ...
# Inside of `scope "/"`:
live "/editor", EditorLive

Now place a minimal EditorLive module, in lib/frampton_web/live/editor_live.ex:

defmodule FramptonWeb.EditorLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~L"""
      <div data-test=”editor”>
        <h1>Hello world!</h1>
      </div>
      """
  end

  def mount(_params, _session, socket) do
    {:ok, socket}
  end
end

And we have a passing test suite! The ~L sigil designates that LiveView should track changes to the content inside. We could keep all of our markup in this render/1 method, but let’s break it out into its own template for demonstration purposes.

Move the contents of render into lib/frampton_web/templates/editor/show.html.leex, and replace EditorLive.render/1 with this one liner: def render(assigns), do: FramptonWeb.EditorView.render("show.html", assigns). And finally, make an EditorView module in lib/frampton_web/views/editor_view.ex:

defmodule FramptonWeb.EditorView do
  use FramptonWeb, :view
  import Phoenix.LiveView
end

Our test should now be passing, and we’ve got a nicely separated out template, view and “live” server. We can keep markup in the template, helper functions in the view, and reactive code on the server. Now let’s move forward to actually render some posts!

Handling User Input

We’ve got four tasks to accomplish before we are done:

  1. Take markdown input from the textarea
  2. Send that input to the LiveServer
  3. Turn that raw markdown into HTML
  4. Return the rendered HTML to the page.

Event binding

To start with, we need to annotate our textarea with an event binding. This tells the liveview.js framework to forward DOM events to the server, using our liveview channel. Open up lib/frampton_web/templates/editor/show.html.leex and annotate our textarea:

<textarea phx-keyup="render_post"></textarea>

This names the event (render_post) and sends it on each keyup. Let’s crack open our web inspector and look at the web socket traffic. Using Chrome, open the developer tools, navigate to the network tab and click WS. In development you’ll see two socket connections: one is Phoenix LiveReload, which polls your filesystem and reloads pages appropriately. The second one is our LiveView connection. If you let it sit for a while, you’ll see that it's emitting a “heartbeat” call. If your server is running, you’ll see that it responds with an “ok” message. This lets LiveView clients know when they've lost connection to the server and respond appropriately.

Now, type some text and watch as it sends down each keystroke. However, you’ll also notice that the server responds with a “phx_error” message and wipes out our entered text. That's because our server doesn’t know how to handle the event yet and is throwing an error. Let's fix that next.

Event handling

We’ll catch the event in our EditorLive module. The LiveView behavior defines a handle_event/3 callback that we need to implement. Open up lib/frampton_web/live/editor_live.ex and key in a basic implementation that lets us catch events:

def handle_event("render_post", params, socket) do
  IO.inspect(params)

  {:noreply, socket}
end

The first argument is the name we gave to our event in the template, the second is the data from that event, and finally the socket we’re currently talking through. Give it a try, typing in a few characters. Look at your running server and you should see a stream of events that look something like this:

There’s our keystrokes! Next, let’s pull out that value and use it to render HTML.

Rendering Markdown

Lets adjust our handle_event to pattern match out the value of the textarea:

def handle_event("render_post", %{"value" => raw}, socket) do

Now that we’ve got the raw markdown string, turning it into HTML is easy thanks to the work we did earlier in our Post module. Fill out the body of the function like this:

{:ok, post} = Post.render(%Post{}, raw)
IO.inspect(post)

If you type into the textarea you should see output that looks something like this:

Perfect! Lastly, it’s time to send that rendered html back to the page.

Returning HTML to the page

In a LiveView template, we can identify bits of dynamic data that will change over time. When they change, LiveView will compare what has changed and send over a diff. In our case, the dynamic content is the post body.

Open up show.html.leex again and modify it like so:

<div class="rendered-output">
  <%= @post.body %>
</div>

Refresh the page and see:

Whoops!

The @post variable will only be available after we put it into the socket’s assigns. Let’s initialize it with a blank post. Open editor_live.ex and modify our mount/3 function:

def mount(_params, _session, socket) do
  post = %Post{}
  {:ok, assign(socket, post: post)}
end

In the future, we could retrieve this from some kind of storage, but for now, let's just create a new one each time the page refreshes. Finally, we need to update the Post struct with user input. Update our event handler like this:

def handle_event("render_post", %{"value" => raw}, %{assigns: %{post: post}} = socket) do
  {:ok, post} = Post.render(post, raw)
  {:noreply, assign(socket, post: post)
end

Let's load up http://localhost:4000/editor and see it in action.

Nope, that's not quite right! Phoenix won’t render this as HTML because it’s unsafe user input. We can get around this (very good and useful) security feature by wrapping our content in a raw/1 call. We don’t have a database and user processes are isolated from each other by Elixir. The worst thing a malicious user could do would be crash their own session, which doesn’t bother me one bit.

Check the edit_posts branch for the final version.

Conclusion

That’s a good place to stop for today. We’ve accomplished a lot! We’ve got a dynamically rendering editor that takes user input, processes it and updates the page. And we haven’t written any JavaScript, which means we don’t have to maintain or update any JavaScript. Our server code is built on the rock-solid foundation of the BEAM virtual machine, giving us a great deal of confidence in its reliability and resilience.

In the next post, we’ll tackle making a shared editor, allowing multiple users to edit the same post. This project will highlight Elixir’s concurrency capabilities and demonstrate how LiveView builds on them to enable some incredible user experiences.



  • Code
  • Back-end Engineering

or

Setting New Project Managers Up for Success

At Viget, we’ve brought on more than a few new Project Managers over the past couple of years, as we continue to grow. The awesome new people we’ve hired have ranged in their levels of experience, but some of them are earlier in their careers and need support from more experienced PMs to develop their skills and flourish.

We have different levels of training and support for new PMs. These broadly fall into four categories:

  • Onboarding: Learning about Viget tools and processes
  • Shadowing: Learning by watching others
  • Pairing: Learning by doing collaboratively
  • Leading: Learning by doing solo

Onboarding

In addition to conducting intro sessions to each discipline at Viget, new Viget PMs go through a lengthy set of training sessions that are specific to the PM lab. These include intros to:

PM tools and resourcesProject processes
Project typesProject checklists
Project taskingProject planning
Budgets, schedules, and resourcingRetrospectives
Working with remote teamsProject kickoffs
Thinking about developmentGithub and development workflow
Tickets, definition, and documentationQA testing
Account management

Shadowing

After PMs complete the onboarding process, they start shadowing other PMs’ projects to get exposure to the different types of projects we run (since the variety is large). We cater length and depth of shadowing based on how much experience a PM has coming in. We also try to expose PMs to multiple project managers, so they can see how PM style differs person-to-person.

We’ve found that it can be most effective to have PMs shadow activities that are more difficult to teach in theory, such as shadowing a PM having a difficult conversation with a client, or shadowing a front-end build-out demo to see how the PM positions the meeting and our process to the client. More straightforward tasks like setting up a Harvest project could be done via pairing, since it’s easy to get the hang of with a little guidance.

Pairing

While shadowing is certainly helpful, we try to get PMs into pairing mode pretty quickly, since we’ve found that most folks learn better by doing than by watching. Sometimes this might mean having a new PM setting up an invoice or budget sheet for a client while a more experienced PM sits next to them, talking them through the process. We’ve found that having a newer PM lead straightforward activities with guidance tends to be more effective than the newer PM merely watching the more experienced PM do that activity.

Another tactic we take is to have both PMs complete a task independently, and then meet and talk through their work, with the more experienced PM giving the less experienced PM feedback. That helps the newer PM think through a task on their own, and gain experience, but still have the chance to see how someone else would have approached the task and get meaningful feedback.

Leading

Once new PMs are ready to be in the driver’s seat, they are staffed as the lead on projects. The timing of when someone shifts into a lead role depends on how much prior experience that person has, as well as what types of projects are actively ready to be worked on.

Most early-career project managers have a behind-the-scenes project mentor (another PM) on at least their first couple projects, so they have a dedicated person to ask questions and get advice from who also has more detailed context than that person’s manager would. For example, mentors often shadow key client and internal meetings and have more frequent check-ins with mentees. This might be less necessary at a company where all the projects are fairly similar, but at Viget, our projects vary widely in scale and services provided, as well as client needs. Because of this, there’s no “one size fits all” process and we have a significant amount of customization per project, which can be daunting to new PMs who are still getting the hang of things.

For these mentorship pairings, we use a mentorship plan document (template here) to help the mentor and mentee work together to define goals, mentorship focuses, and touchpoints. Sometimes the mentee’s manager will take a first stab at filling out the plan, other times, the mentor will start that process.

Management Touchpoints

Along the way, we make sure new PMs have touchpoints with their managers to get the level of support they need to grow and succeed. Managers have regular 1:1s with PMs that are referred to as “project 1:1s”, and are used for the managee to talk through and get advice on challenges or questions related to the projects they’re working on—though really, they can be used for whatever topics are on the managee’s mind. PMs typically have 1:1s with managers daily the first week, two to three times per week after that for the first month or so, then scale down to once per week, and then scale down to bi-weekly after the first six months.

In addition to project 1:1s, we also have monthly 1:1s that are more bigger-picture and focused on goal-setting and progress, project feedback from that person’s peers, reflection on how satisfied and fulfilled they’re feeling in their role, and talking through project/industry interests which informs what projects we should advocate for them to be staffed on. We have a progress log template that we customize per PM to keep track of goals and progress.

We try to foster a supportive environment that encourages growth, feedback, and experiential learning, but also that lets folks have the autonomy to get in the driver’s seat as soon as they’re comfortable. Interested in learning more about what it’s like to work at Viget? Check out our open positions here.




or

Our New Normal, Together

As the world works to mitigate the impact of the COVID-19 pandemic, our thoughts are foremost with those already ill from the virus and those on the frontlines, slowing its spread. The bravery and commitment of healthcare workers everywhere is an inspiration.

While Viget’s physical offices are effectively closed, we’re continuing to work with our clients on projects that evolve by the day. Viget has been working with distributed teams to varying degrees for most of our 20-year history, and while we’re comfortable with the tools and best practices that make doing so effective, we realize that some of our clients are learning as they go. We’re here to help.

These are unprecedented times, but our business playbook is clear: Take care of each other. We’re in this together.

Our People Team is meeting with everyone on our staff to confirm their work-from-home situation. Do they have family or roommates they can rely on in an emergency? How are they feeling physically and mentally? Do they have what they need to be productive? As a team, we’re working extra hard to communicate. Andy hosts and records video calls to answer questions anyone has about the crisis, and our weekly staff meeting schedule will continue. Recognizing that our daily informal group lunches are a vital social glue in our offices, Aubrey has organized a virtual lunch table Hangout, allowing our now fully-distributed team to catch up over video. It ensures we have some laughs and helps keep us feeling connected.

Our project teams are well-versed in remote collaboration, but we understand that not all client projects can proceed as planned. We’re doing our best to accommodate evolving schedules while keeping the momentum on as many projects as possible. For all of our clients, we’re making clear that we think long-term. We’re partners through this, and can adapt to help our clients not just weather the storm, but come through it stronger when possible. Some clients have been forced to pause work entirely, while others are busier than ever.

Viget has persevered through many downturns -- the dot com crash, 9/11, the 2008 financial crisis, and a few self-inflicted close-calls. In retrospect, it’s easy to reflect on how these situations made us stronger, but mid-crisis it can be hard to stay positive. The consistent lesson has been that taking care of each other -- co-workers, clients, partners, community peers -- is what gets us through. It motivates our hard work, it focuses our priorities and collaboration, and inspires us to do what needs to be done.

I don’t know for certain how this crisis will play out, but I know that all of us at Viget will be doing everything we can to support each other as we go through it together.



  • News & Culture

or

A Viget Exploration: How Tech Can Help in a Pandemic

Viget Explorations have always been the result of our shared curiosities. They’re usually a spontaneous outcome of team downtime and a shared problem we’ve experienced. We use our Explorations to pursue our diverse interests and contribute to the conversations about building a better digital world.

As the COVID-19 crisis emerged, we were certainly experiencing a shared problem. As a way to keep busy and manage our anxieties, a small team came together to dive into how technology has helped, and, unfortunately, hindered the community response to the current pandemic.

We started by researching the challenges we saw: information overload, a lack of clarity, individual responsibility, and change. Then we brainstormed possible technical solutions that could further improve how communities respond to a pandemic. Click here to see our Exploration on some possible ways to take the panic out of pandemics.

While we aren’t currently pursuing the solutions outlined in the Exploration, we’d love to hear what you think about these approaches, as well as any ideas you have for how technology can help address the outlined challenges.

Please note, this Exploration doesn’t provide medical information. Visit the Center for Disease Control’s website for current information and COVID-19, its symptoms, and treatments.

At Viget, we’re adjusting to this crisis for the safety of our clients, our staff, and our communities. If you’d like to hear from Viget's co-founder, Brian Williams, you can read his article on our response to the situation.



  • News & Culture

or

CLI Equivalents for Common MAMP PRO and Sequel Pro Tasks

Working on website front ends I sometimes use MAMP PRO to manage local hosts and Sequel Pro to manage databases. Living primarily in my text editor, a terminal, and a browser window, moving to these click-heavy dedicated apps can feel clunky. Happily, the tasks I have most frequently turned to those apps for —starting and stopping servers, creating new hosts, and importing, exporting, deleting, and creating databases— can be done from the command line.

I still pull up MAMP PRO if I need to change a host's PHP version or work with its other more specialized settings, or Sequel Pro to quickly inspect a database, but for the most part I can stay on the keyboard and in my terminal. Here's how:

Command Line MAMP PRO

You can start and stop MAMP PRO's servers from the command line. You can even do this when the MAMP PRO desktop app isn't open.

Note: MAMP PRO's menu icon will not change color to reflect the running/stopped status when the status is changed via the command line.

  • Start the MAMP PRO servers:
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd startServers
  • Stop the MAMP PRO servers:
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd stopServers
  • Create a host (replace host_name and root_path):
/Applications/MAMP PRO.app/Contents/MacOS/MAMP PRO cmd createHost host_name root_path

MAMP PRO-friendly Command Line Sequel Pro

Note: if you don't use MAMP PRO, just replace the /Applications/MAMP/Library/bin/mysql with mysql.

In all of the following commands, replace username with your user name (locally this is likely root) and database_name with your database name. The -p (password) flag with no argument will trigger an interactive password prompt. This is more secure than including your password in the command itself (like -pYourPasswordHere). Of course, if you're using the default password root is not particular secure to begin with so you might just do -pYourPasswordHere.

Setting the -h (host) flag to localhost or 127.0.0.1 tells mysql to look at what's on localhost. With the MAMP PRO servers running, that will be the MAMP PRO databases.

# with the MAMP PRO servers running, these are equivalent:
# /Applications/MAMP/Library/bin/mysql -h 127.0.0.1 other_options
# and
# /Applications/MAMP/Library/bin/mysql -h localhost other_options

/Applications/MAMP/Library/bin/mysql mysql_options # enter. opens an interactive mysql session
mysql> some command; # don't forget the semicolon
mysql> exit;
  • Create a local database
# with the MAMP PRO servers running
# replace `username` with your username, which is `root` by default
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p -e "create database database_name"

or

# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p # and then enter
mysql> create database database_name; # don't forget the semicolon
mysql> exit

    MAMP PRO's databases are stored in /Library/Application Support/appsolute/MAMP PRO/db so to confirm that it worked you can

ls /Library/Application Support/appsolute/MAMP PRO/db
# will output the available mysql versions. For example I have
mysql56_2018-11-05_16-25-13     mysql57

# If it isn't clear which one you're after, open the main MAMP PRO and click
# on the MySQL "servers and services" item. In my case it shows "Version: 5.7.26"

# Now look in the relevant MySQL directory
ls /Library/Application Support/appsolute/MAMP PRO/db/mysql57
# the newly created database should be in the list
  • Delete a local database
# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p -e "drop database database_name"
  • Export a dump of a local database. Note that this uses mysqldump not mysql.
# to export an uncompressed file
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysqldump -h localhost -u username -p database_name > the/output/path.sql

# to export a compressed file
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysqldump -h localhost -u username -p database_name | gzip -c > the/output/path.gz

  • Export a local dump from an external database over SSH. Note that this uses mysqldump not mysql.

# replace `ssh-user`, `ssh_host`, `mysql_user`, `database_name`, and the output path

# to end up with an uncompressed file
ssh ssh_user@ssh_host "mysqldump -u mysql_user -p database_name | gzip -c" | gunzip > the/output/path.sql

# to end up with a compressed file
ssh ssh_user@ssh_host "mysqldump -u mysql_user -p database_name | gzip -c" > the/output/path.gz
  • Import a local database dump into a local database
# with the MAMP PRO servers running
# replace `username` (`root` by default) and `database_name`
/Applications/MAMP/Library/bin/mysql -h localhost -u username -p database_name < the/dump/path.sql
  • Import a local database dump into a remote database over SSH. Use care with this one. But if you are doing it with Sequel Pro —maybe you are copying a Craft site's database from a production server to a QA server— you might as well be able to do it on the command line.
ssh ssh_user@ssh_host "mysql -u username -p remote_database_name" < the/local/dump/path.sql


For me, using the command line instead of the MAMP PRO and Sequel Pro GUI means less switching between keyboard and mouse, less opening up GUI features that aren't typically visible on my screen, and generally better DX. Give it a try! And while MAMP Pro's CLI is limited to the essentials, command line mysql of course knows no limits. If there's something else you use Sequel Pro for, you may be able to come up with a mysql CLI equivalent you like even better.



  • Code
  • Front-end Engineering
  • Back-end Engineering

or

A Parent’s Guide to Working From Home, During a Global Pandemic, Without Going Insane

Though I usually enjoy working from Viget’s lovely Boulder office, during quarantine I am now working from home while simultaneously parenting my 3-year-old daughter Audrey. My husband works in healthcare and though he is not on the front lines battling COVID-19, he is still an essential worker and as such leaves our home to work every day.

Some working/parenting days are great! I somehow get my tasks accomplished, my kid is happy, and we spend some quality time together.

And some days are awful. I have to ignore my daughter having a meltdown and try to focus on meetings, and I wish I wasn’t in this situation at all. Most days are somewhere in the middle; I’m just doing my best to get by.

I’ve seen enough working parent memes and cries for help on social media to know that I’m not alone. There are many parents out there who now get to experience the stress and anxiety of living through a global pandemic while simultaneously navigating ways to stay productive while working from home and being an effective parent. Fun isn’t it?

I’m not an expert on the matter, but I have found a few small things that are making me feel a bit more sane. I hope sharing them will make someone else’s life easier too.

Truths to Accept

First, let’s acknowledge some truths about this new situation we find ourselves in:

Truth 1: We’ve lost something.

Parents have lost more than daycare and schools during this epidemic. We’ve lost any time that we had for ourselves, and that was really valuable. We no longer have small moments in the day to catch up on our personal lives. I no longer have a commute to separate my work duties from my mom duties, or catch up with my friends, or just be quiet.

Truth 2: We’re human.

The reason you can’t be a great employee and a great parent and a great friend and a great partner or spouse all day every day isn’t because you’re doing a bad job, it’s because being constantly wonderful in all aspects of your life is impossible. Pick one or two of those things a day to focus on.

Truth 3: We’re all doing our best.

This is the most important part of this article. Be kind to yourselves. This isn’t easy, and putting so much pressure on yourself that you break isn’t going to make it any easier.

Work from Home Goals

Now that we’ve accepted some truths about our current situation, let’s set some goals.

Goal 1: Do Good Work

At Viget, and wherever you work, with kids or without we all want to make sure that the quality of our work stays up throughout the pandemic and that we can continue to be reliable team members and employees to the best of our abilities.

Goal 2: Stay Sane

We need to figure out ways to do this without sacrificing ourselves entirely. For me, this means fitting my work into normal work hours as much as possible so that I can still have some downtime in the evenings.

Goal 3: Make This Sustainable

None of us knows how long this will last but we may as well begin mentally preparing for a long haul.

Work from Home Rules

Now, there are some great Work from Home Rules that apply to everyone with or without kids. My coworker Paul Koch shared these with the Viget team a Jeremy Bearimy ago and I agree this is also the foundation for working from home with kids.

  1. When you’re in a remote meeting, minimize other windows to stay focused
  2. Set a schedule and avoid chores*
  3. Take breaks away from the screen
  4. Plan your workday on the calendar+
  5. Be mindful of Slack and social media as a distraction
  6. Use timers+
  7. Keep your work area separate from where you relax
  8. Pretend that you’re still WFW
  9. Experiment and figure out what works for you

In the improv spirit I say “Yes, AND….” to these tips. And so, here are my adjusted rules for WFH while kiddos around: These have both been really solid tools for me, so let’s dig in.

Daily flexible schedule for kids

Day Planning: Calendars and Timers

A few small tweaks and adjustments make this even more doable for me and my 3-year-old. First- I don’t avoid chores entirely. If I’m going up and down the stairs all day anyway I might as well throw in a load of laundry while I’m at it. The more I can get done during the day means a greater chance of some down time in the evening.

Each morning I plan my day and Audrey’s day:

My Work Day:

Audrey's Day

Identify times of day you are more likely to be focus and protect them. For me, I know I have a block of time from 5-7a before Audrey wakes up and again during “nap time” from 1-3p.I built a construction paper “schedule” that we update and reorganize daily. We make the schedule together each day. She feels ownership over it and she gets to be the one who tells me what we do next.
Look at your calendar first thing and make adjustments either in your plans or move meetings if you have to.I’m strategic about screen time- I try to schedule it when I have meetings. It also helps to schedule a physical activity before screen time as she is less likely to get bored.
Make goals for your day: Tackle time sensitive tasks first. Take care of things that either your co-workers or clients are waiting on from you first, this will help your day be a lot less stressful. Non-time sensitive tasks come next- these can be done at any time of day.We always include “nap time” even though she rarely naps anymore. This is mostly a time for us both to be alone.

When we make the schedule together it also helps me understand her favorite parts of the day and reminds me to include them.

Once our days are planned, I also use timers to help keep the structure of the day. (I bought a great alarm clock for kids on Amazon that turns colors to signal bedtime and quiet time. It’s been hugely worth it for me.)

Timers for Me:

Timers for Audrey:

More than ever, I rely on a time tracking timer. At Viget we use Harvest to track time, and it has a handy built in timer, but there are many apps or online tools that could help you keep track of your time as well.Audrey knows what time she can come out of her room in the morning. If she wakes up before the light is green she plays quietly in her room.
I need a timer because the days and hours are bleeding together- without tracking as I go it would be really hard for me to remember when I worked on certain projects or know for certain if I gave Viget enough time for the day.She knows how long “nap time” is in the afternoon.
Starting and stopping the timer helps me turn on and off “work mode”, which is a helpful sanity bonus.Perhaps best of all I am not the bad guy! “Sorry honey, the light isn’t green yet and there really isn’t anything mommy can do about it” is my new favorite way to ensure we both get some quiet time.

Work from Home Rules: Updated for Parents

Finally, I have a few more Work from Home Rules for parents to add to the list:

  1. Minimize other windows in remote meetings
  2. Set a schedule and fit in some chores if time allows
  3. Take breaks away from the screen
  4. Schedule both your and your kids’ days
  5. Be mindful of Slack and social media as a distraction
  6. Use timers to track your own time and help your kids understand the day
  7. Keep your work area separate from where you relax
  8. Pretend that you’re still WFW
  9. Experiment and figure out what works for you
  10. Be prepared with a few activities
    • Each morning, have just ONE thing ready to go. This can be a worksheet you printed out, a coloring station setup, a new bag of kinetic sand you just got delivered from Amazon, a kids dance video on YouTube or an iPad game. Recently I started enlisting my mom to read stories on Facetime. The activity doesn’t have to be new each day but (especially for young kids) it has to be handy for you to start up quickly if your schedule changes
  11. Clearly communicate your availability with your team and project PMs
    • Life happens. Some days are going to be hard. Whatever you do, don’t burn yourself out or leave your team hanging. If you need to move a meeting or take a day off, communicate that as early and as clearly as you can.
  12. Take PTO if you can
    • None of us are superheroes. If you’re feeling overwhelmed- take a look at the next few days and figure out which one makes the most sense for you to take a break.
  13. Take breaks to be alone without doing a task
    • Work and family responsibilities have blended together, there’s almost no room for being alone. If you can find some precious alone time don’t use it to fold laundry or clean the bathroom. Just zone out. I think we all really need this.

Last but not least, enjoy your time at home if you can. This is an unusual circumstance and even though it’s really hard, there are parts that are really great too.

If you have some great WFH tips we’d love to hear about them in the comments!




or

Should you use Userbase for your next static site?

During the winter 2020 Pointless Weekend, we built TrailBuddy (working app coming soon). Our team consisted of four developers, two project managers, two front-end developers, a digital-analyst, a UXer, and a designer. In about 48 hours, we took an idea from Jeremy Field’s head to a (mostly) working app. We broke up the project in two parts:. First, a back-end that crunches trail, weather, and soil data. That data is exposed via a GraphQL API for a web app to consume.

While developers built the API, I built a static front end using Next.js. Famously, static front-ends don’t have a database, or a concept of “users.” A bit of functionality I wanted to add was saving favorite trails. I didn’t want to be hacky about it, I needed some way to add users and a database. I knew it’d be hard for the developers to set this up as part of the API, they had their hands full with all the #soil-soil-soil-soil-soil (a slack channel dedicated solely to figuring out our soil data problem—those were plentiful.) I had been looking for an excuse to use Userbase, and this seemed like as good a time as any.

A textbook Userbase use case

“When would I use it?” The Usebase site lists these reasons:

  • If you want to build a web app without writing any backend code.
  • If you never want to see your users' data.
  • If you're tired of dealing with databases.
  • If you want to radically simplify your GDPR compliance.
  • And if you want to keep things really simple.

This was a perfect fit for my problem. I didn’t want to write any more backend code for this. I didn’t want to see our user’s data, I don’t care to know anyone’s favorite trails.* A nice bonus to not having users in our backend was not having to worry about keeping their data safe. We don’t have their data at all, it’s end-to-end encrypted by Userbase. We can offer a reasonable amount of privacy for free (well for the price of using Userbase: $49 a year.) I am not tired of dealing with databases, but I’d rather not. I don’t think anyone doesn’t want to simplify their GDPR compliance. Finally, given our tight timeline I wanted nothing more than to keep things really simple.

A sign up form that I didn't have to write a back-end for

Using Userbase

Userbase can be tried for free, so I set aside thirty minutes or so to do a quick proof of concept to make sure this would work out for us. I made an account and followed their Quickstart. Userbase is a fundamentally easy tool to use, but their quickstart is everything I’d want out of a quickstart:

  • Written in the most vanilla way possible (just HTML and vanilla JS). This means I can adapt it to my needs, in this case React using Next.js
  • Easy to follow, it does the most barebones tour of the functionality you can expect to get out of the SDK (software development kit.) In other words it is quick and it is a start
  • It has a live demo and code samples you can download and run yourself

It didn’t take long after that to integrate Userbase into our app with more help from their great docs. I debated whether to add code samples of what we did here, and I didn’t because any reader would be better off using the great quickstart and docs Userbase provides—they are that clear, and that good. Depending on your use case you’ll need to adapt the examples to your needs, for us the trickiest things were creating a top level authentication context to manage users in the app, and a custom hook to encapsulate all the logic for setting, updating, and deleting favourite trails in the app. Userbase’s SDK worked seamlessly for us.

A log in form that I didn't have to write a back-end for

Is Userbase for you?

Maybe. I am definitely a fan, so much so that this blog post probably reads like an advert. Userbase saved me a ton of time in this project. It reminded me of “The All Powerful Front End Developer” talk by Chris Coyer. I don’t fully subscribe to all the ideas in that talk, but it is nice to have “serverless” tools like Userbase, and all the new JAMstacky things. There are limits to the Userbase serverless experience in terms of scale, and control. Obviously relying on a third party for something always carries some (probably small) risk—it’s worth noting Usebase includes a note on their pricing page that says “You can host it yourself always under your control, or we can run it for you for a full serverless experience”—Still, I wouldn’t hesitate this to use in future projects.

One of the great things about Viget and Pointless Weekend is the opportunity to try new things. For me that was Next.js and Userbase for Trailbuddy. It doesn’t always work out (in fact this is my first pointless weekend where a risk hasn’t blown up in my face) but it is always fun. Getting to try out Userbase and beginning to think about how we may use it in the future made the weekend worthwhile for me, and it made my job on this project much more enjoyable.

*I will write a future post about privacy conscious analytics in TrailBuddy when I’ve figured that out. I am looking into Fathom Analytics for that.



  • Code
  • Front-end Engineering

or

Global Gitignore Files Are Cool and So Are You

Setting it up

First, here's the config setup you need to even allow for such a radical concept.

  1. Define the global gitignore file as a global Git configuration:

    git config --global core.excludesfile ~/.gitignore
    

    If you're on OSX, this command will add the following config lines in your ~/.gitconfig file.

    [core]
      excludesfile = /Users/triplegirldad/.gitignore
    
  2. Load that ~/.gitignore file up with whatever you want. It probably doesn't exist as a file yet so you might have to create it first.

Harnessing its incredible power

There are only two lines in my global gitignore file and they are both fairly useful pretty much all the time.

$ cat ~/.gitignore
TODO.md
playground

This 2 line file means that no matter where I am, what project I'm working on, where in the project I'm doing so, I have an easy space to stash notes, thoughts, in progress ideas, spikes, etc.

TODO.md

More often than not, I'm fiddling around with a TODO.md file. Something about writing markdown in your familiar text editor speaks to my soul. It's quick, it's easy, you have all the text editing tricks available to you, and it never does anything you wouldn't expect (looking at you auto-markdown-formatting editors). I use one or two # for headings, I use nested lists, and I ask for nothing more. Nothing more than more TODO.md files that is!

In practice I tend to just have one TODO.md file per project, right at the top, ready to pull up in a few keystrokes. Which I do often. I pull this doc up if:

  • I'm in a meeting and I just said "oh yeah that's a small thing, I'll knock it out this afternoon".
  • I'm halfway through some feature development and realize I want to make a sweeping refactor elsewhere. Toss some thoughts in the doc, and then get back to the task at hand.
  • It's the end of the day and I have to switch my brain into "feed small children" mode, thus obliterating everything work-related from my short term memory. When I open things up the next day and know exactly what the next thing to dive into was.
  • I'm preparing for a big enough refactor and I can't hold it all in my brain at once. What I'd give to have an interactive 3D playground for brain thoughts, but in the meantime a 2D text file isn't a terrible way to plan out dev work.

playground

Sometimes you need more than some human words in a markdown file to move an idea along. This is where my playground directory comes in. I can load this directory up with code that's related to a given project and keep it out of the git history. Because who doesn't like a place to play around.

I find that this directory is more useful for long running maintenance projects over fast moving greenfield ones. On the maintenance projects, I tend to find myself assembling a pile of scripts and experiments for various situations:

  • The client requests a one-time obscure data export. Whip up some CSV generation code and save that code in the playground directory.
  • The client requests a different obscure data export. Pull up the last time you did something vaguely similar and save yourself the startup time.
  • A batch of data needs to be imported just once. Might as well stash that in the chance that "just once" is actually "just a few times".
  • Kicking the tires on an integration with a third party service.

Some of these playground files end up being useful more times than I can count (eg: the ever-changing user_export.rb script). Some items get promoted into application code, which is always fun. But most files here serve their purpose and then wither away. And that's fine. It's a playground, anything goes.

Wrapping up

Having a personal space for project-specific notes and code has been helpful to me over the years as a developer on multiple projects. If you have your own organizational trick, or just want to brag about how you memorize everything without any markdown files, let me know in the comments below!




or

"I always hated that word—marketing—and I hate it now. Because for me, and this may sound simplistic,..."

““I always hated that word—marketing—and I hate it now. Because for me, and this may sound simplistic, the key to marketing is to make something people want. When they want it, they buy it. When they buy it, you have sales. So the product has to speak. The product is what markets things.””

- Interview with Tom Ford.




or

"In conceptual art the idea or concept is the most important aspect of the work. When an artist uses..."

“In conceptual art the idea or concept is the most important aspect of the work. When an artist uses a conceptual form of art, it means that all of the planning and decisions are made beforehand and the execution is a perfunctory affair. The idea becomes a machine that makes the art. This kind of art is not theoretical or illustrative of theories; it is intuitive, it is involved with all types of mental processes and it is purposeless. It is usually free from the dependence on the skill of the artist as a craftsman.”

- Artist Sol Lewitt on conceptual art.




or

Illustrator Tutorial: How to Create an iPhone Icon

Welcome back to another Adobe Illustrator based tutorial, in which we're going to take a close look behind the process of creating a simple iPhone icon, using nothing more than some basic geometric shapes that we're going to adjust here and there. 1. Set Up a New Project File As with any new project, we’re […]

The post Illustrator Tutorial: How to Create an iPhone Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create a Simple Computer Icon

In today’s tutorial, we're going to take a close look behind the process of creating a simple computer icon, and see how easy it is to build one of our one using nothing more than some basic geometric shapes. 1. Set Up a New Project File As with any new project, we’re going to kick […]

The post Illustrator Tutorial: How to Create a Simple Computer Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create a Folder Icon

In today’s tutorial, we’re going to take an in-depth look behind the process of creating a folder icon, and see how easy it is to build one from scratch using nothing more than a couple of basic geometric shapes, which we’re going to adjust here and there. So, assuming you already have Illustrator up and […]

The post Illustrator Tutorial: How to Create a Folder Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create a Watch Icon

Welcome back to another Illustrator based tutorial, in which we’re going to learn how to create a simple watch icon, using nothing more than a couple of basic geometric shapes and tools. So, assuming you already have the software running in the background, bring it up and let’s jump straight into it! 1. Set Up […]

The post Illustrator Tutorial: How to Create a Watch Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create an Icognito Icon

Welcome back to another Illustrator based tutorial, in which we’re going to take a close look behind the process of creating an incognito icon, using nothing more than a couple of simple shapes and tools. So, assuming you already have the software running in the background, bring it up and let’s jump straight into it! […]

The post Illustrator Tutorial: How to Create an Icognito Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create an Ice Cream icon

In today’s tutorial, we’re going to take a quick look at the process of creating an Ice Cream icon, and learn how easy it is to build one from scratch using nothing more than a couple of basic geometric shapes that we’re going to adjust here and there. So, assuming you already have the software […]

The post Illustrator Tutorial: How to Create an Ice Cream icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create a Notification Bell Icon

n today’s tutorial, we’re going to take a quick look behind the process of creating a notification bell icon, and see how easy it is to do so using nothing more than a couple of basic geometric shapes and tools. So, assuming you already have the software up and running, let’s jump straight into it! […]

The post Illustrator Tutorial: How to Create a Notification Bell Icon appeared first on Bittbox.




or

Illustrator Tutorial: How to Create a Recycle Bin Notification Icon

Welcome back to another Illustrator based tutorial, in which we’re going to learn how to create a recycle bin notification icon, using nothing more than a couple of basic geometric shapes that we’re going to adjust here and there. So, assuming you already have the software running in the background, bring it up and let’s […]

The post Illustrator Tutorial: How to Create a Recycle Bin Notification Icon appeared first on Bittbox.




or

The State – Sort of – of HTML5 Audio

The State – Sort of – of HTML5 Audio Scott Schiller discusses the high level of hype around HTML5 and CSS3. The two specs render ”many years of feature hacks redundant by replacing them with native features,” he writes in an insightful blog. Blogging, he says: CSS3’s border-radius, box-shadow, text-shadow and gradients, and HTML5’s <canvas>, Read the rest...




or

Code injection, error throwing

In a blog, Opera Software Developer Relations team member Tiffany B. Brown looks at code injection, error throwing and handling and mobile debugging. She notes Opera Dragonfly and its remote debug features provide a way to debug mobile sites from their desktop. Brown mentions WebKit’s recently added remote debugging capabilities, folded into Google Chrome developer Read the rest...




or

A simple random bit on var selector

Isobar’s Rob Larsen suggests that there is often a need to build CSS selectors dynamically when building applications. ”This is typically some existing pattern paired with a loop counter or something pulled from a data attribute,” he writes on his blog. His choice is to create a variable called ”selector” and ”to craft the selector Read the rest...




or

Intel’s Parallel Extensions for JavaScript

Intel’s Parallel Extensions for JavaScript, code named River Trail, hooks into on-chip vector extensions to improve performance of Web applications. Details of Intel’s attempt to get on the JavaScript juggernaut emerged last month at its developer event. The prototype JavaScript extension offered by Intel is intended to allow JavaScript apps to take advantage of modern parallel Read the rest...




or

Adobe to forgo Flash plug-in for mobile devices

Earlier this week, Adobe VP and General Manager Danny Winokur disclosed that the company has concluded that HTML5 is ”the best solution for creating and deploying content in the browser across mobile platforms.” The company said it would stop building Flash to run on mobile browsers. In a blog post on the new focus of Read the rest...




or

HipHop Virtual Machine for PHP

Facebook Software Engineer and HipHop for PHP team member Jason Evans provides details on Facebook’s move to a new high-performance PHP virtual machine. Described by Evans is ”a new PHP execution engine based on the HipHop language runtime that we call the HipHop Virtual Machine (hhvm).” He sees it as replacement for the HipHop PHP Read the rest...




or

Vert.x ramblings: Asynchronous network, your time has come

With the debut of Vert.x, the asynchronous framework is reaching an inflection point, suggests Andrew Cholakian. With Vert.x, the software is packaged together in such a way as to be extremely practical, he states. For some JVM zealots, Vert.x may meet needs recently and apparently addressed by node.js. Vert.x is an asynchronous application server – Read the rest...











or

WPCampus 2019 WP Rig Workshop

This post contains the slides for and links to all the things you need to follow my WP Rig workshop at WP Campus 2019, including a couple of verbose code examples for complex walk-throughs. WP Rig itself: WP Rig WP Rig Wiki Free LinkedIn Learning course on WP Rig VS Code extensions EditorConfig ESLint PHP […]

The post WPCampus 2019 WP Rig Workshop appeared first on MOR10.




or

ASPIRE: An Acronym for Better Web Practice

Sometimes interesting things happen on Twitter. Last week Scott Jehl proposed ASPIRE as an acronym for the practices we should follow as web designers and developers. From the resulting blog post: Great websites should aspire to be: Accessible to folks with varying cognitive and physical abilities and disabilities Secure and reliable for storing, manipulating, and transferring information Performant on average devices […]

The post ASPIRE: An Acronym for Better Web Practice appeared first on MOR10.




or

The Best Free Zoom Backgrounds to Make Your Video Conferencing More Fun

If you’re a remote worker, you may have plenty of experience with video conferencing as a way to communicate with clients, team members, or other colleagues. But with millions of additional...

Click through to read the rest of the story on the Vandelay Design Blog.




or

14 Visual Content Marketing Statistics to Know for 2019

Online marketing with visual content continues to grow and drive tons of traffic. The team at Venngage gathered together the latest data in the 14 Visual Content Marketing Statistics to Know for 2019 infographic and built it using their own tool.

From Nadya Khoja at Venngage:

Two years ago I asked 300 different online marketers to help me figure out how they were using visual content as part of their marketing strategies in 2016 and their predictions for 2017.

This year I wanted to see if there were any changes in how marketers were creating visuals, and what kind of content engagement they were seeing.

I also asked a couple of additional questions to see how the use of various visual formats impacted their blogging strategies.

Conclusion:

The data says it all–visual content isn’t going anywhere any time soon. Not only are more brands leveraging the use for of visuals for various social media platforms, but there is a lot of added benefit when it comes to SEO and organic rankings as well, particularly in Google’s image search results.

And of course, creating engaging visual content is a surefire way to resonate with your audience and communicate your ideas more effectively.

There are a few things to unravel here:

  • It’s good survey data, but take it with a grain of salt. Venngage is a visual design tool, sharing data about visual content marketing.

  • The infographic is a fantastic format to summarize the survey results and use in social media to draw in readers to the full article.

  • The infographic is built using Venngage, so it’s also a great way to showcase what their design tool is capable of. In fact, clicking on the infographic gives you the opportunity to use this design as a template for designing your own infographic.

  • Sections 5 & 10 are disappointing visually. There are no data visualizations, just a bunch of percentage values shown in text.

  • I’m not a fan of the bright color scheme, and it’s visually distracting from highlighting insights in the data.

  • The article still references 2018 data, even though the infographic has been updated with newer data from 2019.




or

Google Ranking Factors 2020: Facts and Myths

Google’s ranking algorithm continues to get more and more complex, and the Ranking Factors 2020: Facts and Myths infographic from Link-Assistant tries to break through some of the misinformation that’s out there.

It seems a little while ago that Google hinted at having 200+ ranking factors. Though in fact, it happened in the year of 2009, and we are heading to 2020 now.

Google has drastically evolved over the past ten years. Today, neural matching — an AI-based method — processes about 30% of all searches, and Google can recognize concepts behind keywords. They have introduced RankBrain, mobile-first indexing, and HTTPS. As we need to adapt to changes and find ways to get atop of SERPs, the topic of ranking factors remains as fresh as ever.

So let's have a look at what ranking factors to consider in 2020, and what ranking myths to leave behind.

I have mixed feelings about this infographics design:

Good:

  • It’s a concise summary of very complex information that’s laid out in the more detailed, full article.

  • The infographic is a handy reference sheet and great for use in social media as promotion for the article.

  • Clean arrangement that’s easy to read from top-to-bottom

Bad:

  • Almost all text.

  • Not that there’s much data that could have been visualized with charts, but some visual design elements would have made the infographic easier to read and more enticing to readers.

  • Text URL to the article! When the infographic gets shared, how are readers supposed to find the article when it’s not linked??? Put it in the footer on the infographic!