1

Sony Xperia Z1 Compact Complete Guide

Have you got yourself a Sony Xperia Z1 Compact but not sure how to do something on it? Don’t worry, we’ve come up with a comprehensive guide for all the things your handset is capable of. Navigate the various sections using the links below. If you can’t find what you’re looking for just leave a … Continue reading Sony Xperia Z1 Compact Complete Guide




1

Record-Low 2016 Antarctic Sea Ice Due to ‘Perfect Storm’ of Tropical, Polar Conditions

By Hannah Hickey UWNEWS While winter sea ice in the Arctic is declining so dramatically that ships can now navigate those waters without any icebreaker escort, the scene in the Southern Hemisphere is very different. Sea ice area around Antarctica … Continue reading




1

Top 15 Digital Scrapbooking Downloads (Free & Paid)

Scrapbooking can be a fun way to capture important moments in life and with our list of the Top 15 Scrapbooking Resources, you can start right away!




1

Top 10 Best Courses on Domestika (in English)

For those professionals looking to share not only their projects but to connect with other creatives, learn from them, and even find employment in the creative field, a new option entering the English market is Domestika. With its expansive forums and thousands of projects being shared by creatives from all over the world, Domestika is an amazing resource to explore. One of their biggest features is their online courses to help you learn new skills and with that in mind, we wanted to shine a spotlight on the 10 Best English Courses on Domestika so you can jump right in and get started! So, if you’re ready, let’s get started! Bundle 3 Courses & Save 30% (Ends May 6) Domestika are offering a further 30% off if you bundle 3 courses. » Click here to start bundling.    Top 10 Best English Courses on Domestika Logo Design: From Concept to Presentation with Sagi Haviv – $19 Transforming your creative ideas into personal projects – $15 Creativity Face to Face: A Playful Collage Journey – $12 Digital Painting for Characters: Color and Light – $14 Creation of an Original Logo from Scratch – $14 The Art of Record Covers: Illustration Meets […]





1

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

1

Committed to the wrong branch? -, @{upstream}, and @{-1} to the rescue

I get into this situation sometimes. Maybe you do too. I merge feature work into a branch used to collect features, and then continue development but on that branch instead of back on the feature branch

git checkout feature
# ... bunch of feature commits ...
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# deploy qa-environment to the QA remote environment
# ... more feature commits ...
# oh. I'm not committing in the feature branch like I should be

and have to move those commits to the feature branch they belong in and take them out of the throwaway accumulator branch

git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

Maybe you prefer

git branch -D qa-environment
git checkout qa-environment

over

git checkout qa-environment
git reset --hard origin/qa-environment

Either way, that works. But it'd be nicer if we didn't have to type or even remember the branches' names and the remote's name. They are what is keeping this from being a context-independent string of commands you run any time this mistake happens. That's what we're going to solve here.

Shorthands for longevity

I like to use all possible natively supported shorthands. There are two broad motivations for that.

  1. Fingers have a limited number of movements in them. Save as many as possible left late in life.
  2. Current research suggests that multitasking has detrimental effects on memory. Development tends to be very heavy on multitasking. Maybe relieving some of the pressure on quick-access short term memory (like knowing all relevant branch names) add up to leave a healthier memory down the line.

First up for our scenario: the - shorthand, which refers to the previously checked out branch. There are a few places we can't use it, but it helps a lot:

Bash
# USING -

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -        # ????
git push
# hack hack hack
# whoops
git checkout -        # now on feature ???? 
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout - # now on qa-environment ????
git reset --hard origin/qa-environment
git merge --no-ff --no-edit -        # ????
git checkout -                       # ????
# on feature and ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

We cannot use - when cherry-picking a range

> git cherry-pick origin/-..-
fatal: bad revision 'origin/-..-'

> git cherry-pick origin/qa-environment..-
fatal: bad revision 'origin/qa-environment..-'

and even if we could we'd still have provide the remote's name (here, origin).

That shorthand doesn't apply in the later reset --hard command, and we cannot use it in the branch -D && checkout approach either. branch -D does not support the - shorthand and once the branch is deleted checkout can't reach it with -:

# assuming that branch-a has an upstream origin/branch-a
> git checkout branch-a
> git checkout branch-b
> git checkout -
> git branch -D -
error: branch '-' not found.
> git branch -D branch-a
> git checkout -
error: pathspec '-' did not match any file(s) known to git

So we have to remember the remote's name (we know it's origin because we are devoting memory space to knowing that this isn't one of those times it's something else), the remote tracking branch's name, the local branch's name, and we're typing those all out. No good! Let's figure out some shorthands.

@{-<n>} is hard to say but easy to fall in love with

We can do a little better by using @{-<n>} (you'll also sometimes see it referred to be the older @{-N}). It is a special construct for referring to the nth previously checked out ref.

> git checkout branch-a
> git checkout branch-b
> git rev-parse --abbrev-rev @{-1} # the name of the previously checked out branch
branch-a
> git checkout branch-c
> git rev-parse --abbrev-rev @{-2} # the name of branch checked out before the previously checked out one
branch-a

Back in our scenario, we're on qa-environment, we switch to feature, and then want to refer to qa-environment. That's @{-1}! So instead of

git cherry-pick origin/qa-environment..qa-environment

We can do

git cherry-pick origin/qa-environment..@{-1}

Here's where we are (🎉 marks wins from -, 💥 marks the win from @{-1})

Bash
# USING - AND @{-1}

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -                # ????
git push
# hack hack hack
# whoops
git checkout -                               # ????
git cherry-pick origin/qa-environment..@{-1} # ????
git push
git checkout -                               # ????
git reset --hard origin/qa-environment
git merge --no-ff --no-edit -                # ????
git checkout -                               # ????
# ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

One down, two to go: we're still relying on memory for the remote's name and the remote branch's name and we're still typing both out in full. Can we replace those with generic shorthands?

@{-1} is the ref itself, not the ref's name, we can't do

> git cherry-pick origin/@{-1}..@{-1}
origin/@{-1}
fatal: ambiguous argument 'origin/@{-1}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

because there is no branch origin/@{-1}. For the same reason, @{-1} does not give us a generalized shorthand for the scenario's later git reset --hard origin/qa-environment command.

But good news!

Do @{u} @{push}

@{upstream} or its shorthand @{u} is the remote branch a that would be pulled from if git pull were run. @{push} is the remote branch that would be pushed to if git push was run.

> git checkout branch-a
Switched to branch 'branch-a'
Your branch is ahead of 'origin/branch-a' by 3 commits.
  (use "git push" to publish your local commits)
> git reset --hard origin/branch-a
HEAD is now at <the SHA origin/branch-a is at>

we can

> git checkout branch-a
Switched to branch 'branch-a'
Your branch is ahead of 'origin/branch-a' by 3 commits.
  (use "git push" to publish your local commits)
> git reset --hard @{u}                                # <-- So Cool!
HEAD is now at <the SHA origin/branch-a is at>

Tacking either onto a branch name will give that branch's @{upstream} or @{push}. For example

git checkout branch-a@{u}

is the branch branch-a pulls from.

In the common workflow where a branch pulls from and pushes to the same branch, @{upstream} and @{push} will be the same, leaving @{u} as preferable for its terseness. @{push} shines in triangular workflows where you pull from one remote and push to another (see the external links below).

Going back to our scenario, it means short, portable commands with a minimum human memory footprint. (🎉 marks wins from -, 💥 marks the win from @{-1}, 😎 marks the wins from @{u}.)

Bash
# USING - AND @{-1} AND @{u}

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -    # ????
git push
# hack hack hack
# whoops
git checkout -                   # ????
git cherry-pick @{-1}@{u}..@{-1} # ????????
git push
git checkout -                   # ????
git reset --hard @{u}            # ????
git merge --no-ff --no-edit -    # ????
git checkout -                   # ????
# ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

Make the things you repeat the easiest to do

Because these commands are generalized, we can run some series of them once, maybe

git checkout - && git reset --hard @{u} && git checkout -

or

git checkout - && git cherry-pick @{-1}@{u}.. @{-1} && git checkout - && git reset --hard @{u} && git checkout -

and then those will be in the shell history just waiting to be retrieved and run again the next time, whether with CtrlR incremental search or history substring searching bound to the up arrow or however your interactive shell is configured. Or make it an alias, or even better an abbreviation if your interactive shell supports them. Save the body wear and tear, give memory a break, and level up in Git.

And keep going

The GitHub blog has a good primer on triangular workflows and how they can polish your process of contributing to external projects.

The FreeBSD Wiki has a more in-depth article on triangular workflow process (though it doesn't know about @{push} and @{upstream}).

The construct @{-<n>} and the suffixes @{push} and @{upstream} are all part of the gitrevisions spec. Direct links to each:



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

    1

    A Viget Glossary: What We Mean and Why it Matters - Part 1

    Viget has helped organizations design and develop award-winning websites and digital products for 20 years. In that time, we’ve been lucky to create long-term relationships with clients like Puma, the World Wildlife Fund, and Privia Health, and, throughout our time working together, we’ve come to understand each others’ unique terminology. But that isn’t always the case when we begin work with new clients, and in a constantly-evolving industry, we know that new terminology appears almost daily and organizations have unique definitions for deliverables and processes.

    Kicking off a project always initiates a flurry of activity. There are contracts to sign, team members to introduce, and new platforms to learn. It’s an exciting time, and we know clients are anxious to get underway. Amidst all the activity, though, there is a need to define and create a shared lexicon to ensure both teams understand the project deliverables and process that will take us from kickoff to launch.

    Below, we’ve rounded up a few terms for each of our disciplines that often require additional explanation. Note: our definitions of these terms may differ slightly from the industry standard, but highlight our interpretation and use of them on a daily basis.

    User Experience

    Research

    In UX, there is a proliferation of terms that are often used interchangeably and mean almost-but-subtly-not the same thing. Viget uses the term research to specifically mean user research — learning more about the users of our products, particularly how they think and behave — in order to make stronger recommendations and better designs. This can be accomplished through different methodologies, depending on the needs of the project, and can include moderated usability testing, stakeholder interviews, audience research, surveys, and more. Learn more about the subtleties of UX research vocabulary in our post on “Speaking the Same Language About Research”.

    Wireframes

    We use wireframes to show the priority and organization of content on the screen, to give a sense of what elements will get a stronger visual treatment, and to detail how users will get to other parts of the site. Wireframes are a key component of website design — think of them as the skeleton or blueprint of a page — but we know that clients often feel uninspired after reviewing pages built with gray boxes. In fact, we’ve even written about how to improve wireframe presentations. We remind clients that visual designers will step in later to add polish through color, graphics, and typography, but agreeing on the foundation of the page is an important and necessary first step.

    Prototypes

    During the design process, it’s helpful for us to show clients how certain pieces of functionality or animations will work once the site is developed. We can mimic interactivity or test a technical proof of concept by using a clickable prototype, relying on tools like Figma, Invision, or Principle. Our prototypes can be used to illustrate a concept to internal stakeholders, but shouldn’t be seen as a final approach. Often, these concepts will require additional work to prepare them for developer handoff, which means that prototypes quickly become outdated. Read more about how and when we use prototypes.

    Navigation Testing (Treejack Testing)

    Following an information architecture presentation, we will sometimes recommend that clients conduct navigation testing. When testing, we present a participant with the proposed navigation and ask them to perform specific tasks in order to see if they will be able to locate the information specified within the site’s new organization. These tests generally focus on two aspects of the navigation: the structure of the navigation system itself, and the language used within the system. Treejack is an online navigation testing tool that we like to employ when conducting navigation tests, so we’ll often interchange the terms “navigation testing” with “treejack testing”.

    Learn more about Viget’s approach to user experience and research




    1

    5 things to Note in a New Phoenix 1.5 App

    Yesterday (Apr 22, 2020) Phoenix 1.5 was officially released ????

    There’s a long list of changes and improvements, but the big feature is better integration with LiveView. I’ve previously written about why LiveView interests me, so I was quite excited to dive into this release. After watching this awesome Twitter clone in 15 minutes demo from Chris McCord, I had to try out some of the new features. I generated a new phoenix app with the —live flag, installed dependencies and started a server. Here are five new features I noticed.

    1. Database actions in browser

    Oops! Looks like I forgot to configure the database before starting the server. There’s now a helpful message and a button in the browser that can run the command for me. There’s a similar button when migrations are pending. This is a really smooth UX to fix a very common error while developing.

    2. New Tagline!

    Peace-of-mind from prototype to production

    This phrase looked unfamiliar, so I went digging. Turns out that the old tagline was “A productive web framework that does not compromise speed or maintainability.” (I also noticed that it was previously “speed and maintainability” until this PR from 2019 was opened on a dare to clarify the language.)

    Chris McCord updated the language while adding phx.new —live. I love this framing, particularly for LiveView. I am very excited about the progressive enhancement path for LiveView apps. A project can start out with regular, server rendered HTML templates. This is a very productive way to work, and a great way to start a prototype for just about any website. Updating those templates to work with LiveView is an easier lift than a full rebuild in React. And finally, when you’re in production you have the peace-of-mind that the reliable BEAM provides.

    3. Live dependency search

    There’s now a big search bar right in the middle of the page. You can search through the dependencies in your app and navigate to the hexdocs for them. This doesn’t seem terribly useful, but is a cool demo of LiveView. The implementation is a good illustration of how compact a feature like this can be using LiveView.

    4. LiveDashboard

    This is the really cool one. In the top right of that page you see a link to LiveDashboard. Clicking it will take you to a page that looks like this.

    This page is built with LiveView, and gives you a ton of information about your running system. This landing page has version numbers, memory usage, and atom count.

    Clicking over to metrics brings you to this page.

    By default it will tell you how long average queries are taking, but the metrics are configurable so you can define your own custom telemetry options.

    The other tabs include process info, so you can monitor specific processes in your system:

    And ETS tables, the in memory storage that many apps use for caching:

    The dashboard is a really nice thing to get out of the box and makes it free for application developers to monitor their running system. It’s also developing very quickly. I tried an earlier version a week ago which didn’t support ETS tables, ports or sockets. I made a note to look into adding them, but it's already done! I’m excited to follow along and see where this project goes.

    5. New LiveView generators

    1.5 introduces a new generator mix phx.gen.live.. Like other generators, it will create all the code you need for a basic resource in your app, including the LiveView modules. The interesting part here is that it introduces patterns for organizing LiveView code, which is something I have previously been unsure about. At first glance, the new organization makes sense and feels like a good approach. I look forward to seeing how this works on a real project.

    Conclusion

    The 1.5 release brings more changes under the hood of course, but these are the first five differences you’ll notice after generating a new Phoenix 1.5 app with LiveView. Congratulations to the entire Phoenix team, but particularly José Valim and Chris McCord for getting this work released.



    • Code
    • Back-end Engineering




    1

    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.




    1

    Where We Go From Here: 10 Thoughts on the Immediate Future of the Web

    I was asked to close out WordCamp Vancouver with a short 20 minute keynote on something interesting. After some thought, I put together a list of 10 trends I see in the web community and where we are headed in the immediate future. 0. The Future Keeps Arriving In my +15 years working on and with the […]

    The post Where We Go From Here: 10 Thoughts on the Immediate Future of the Web appeared first on MOR10.




    1

    2010 – 2019: Decade in Review

    As the decade comes to a close, I thought it would be interesting to look back on the past 10 years. So, rather than posting my regular year in review, here’s an abbreviated trip through the past 10 years of my life, both personal and professional. 2010 The decade started for me in an almost […]

    The post 2010 – 2019: Decade in Review appeared first on MOR10.




    1

    15 Digital Products That Web Designers Can Create and Sell

    There are a number of different ways to make money as a web designer aside from simply creating websites for clients. Many freelancers choose to supplement their income from client work by doing some...

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




    1

    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.




    1

    Get to Know COVID-19

    Made withVisme Infographic Maker

    Get To Know COVID-19 is an interactive infographic build on the Visme platform that allows for the inclusion of animation, URL links, interactive content and playable videos.

    Of course it’s timely information, but this is also an experiment with embedding the fully interactive infographic here in the blog post. A designer can go overboard, but good use of animation can attract the reader’s attention to important information or better demonstrate data. Below is the static JPG image of the infographic.

    I am disappointed that the data included in the infographic isn’t visualized. It’s just shown as text numbers. That doesn’t give the reader any context or visual cues on how to perceive those data values.

    What is Coronavirus/COVID-19?

    According to the World Health Organization (WHO), COVID-19 is a respiratory disease caused by a newly discovered type of coronavirus.

    This new strain of virus, also known as SARS-CoV-2, has not been previously identified in humans. It can be transmitted from person to person via respiratory droplets, such as when an infected person coughs or sneezes within 6 feet of contact.

    The WHO has declared the virus as a global pandemic and a crisis unlike any other in the 75-year history of the UN.




    1

    DataViz Community COVID-19 Resources

    Not an infographic today.

    Free online classes, discounts on software, extended trial periods, free online data sources, etc. as a result of the COVID-19 pandemic.

    As the Organizer for the DFW Data Visualization Meetup Group, I've started this publicly viewable Google Sheet for the local DataViz community listing various resources that companies are making available during the pandemic. Turns out, these are valuable to DataViz designers everywhere, not just DFW, so I'm sharing the link with all of you.

    I’ll continue to update this list as I learn about new resources during the pandemic. Please use the submission link in the spreadsheet if you know of any DataViz-related offers or deals I should add!

    -Randy




    1

    10 Things To Do Before Any Video Interview

    We’re all working from home, and that include job interviews, news interviews, class lectures, webinars, presentations to customers and even just business meetings. The 10 Things to Do Before Any Video Interview infographic from Kickresume is a great last-minute checklist before you turn on your webcam!

    In the end, you can take this infographic as a checklist. You can use it to prepare for your job interview or any other video conference call.

    And, oh boy, are we going to make many more of those. Sure, it took a global pandemic for companies to recognize the value of working from home but now there’s no going back. Video conference calls are here to stay. (I personally hate it but even I should probably get used to it. Damn.)

    Anyway, good luck at your job interview!

    I would have preferred more visual elements, but I like that this is a tightly focused infographic with a clear, useful message to a broad audience. This is one of the best uses for an infographic: an informative topic, related to the industry of the publishing company, with a popular, trending topic. This design checks all the boxes.

    Designers have to remember that the infographic image file will often be shared by itself, so it always helps to include a few more thins in the footer:

    • The Infographic Landing Page URL (not just the company home page). This will help readers find the full infographic and the article that went along with it. Don’t make people search for it on your website.

    • A copyright or Creative Commons statement is always a good idea when you publishing an infographic




    1

    COVID-19 #Coronavirus Infographic Data Pack

    COVID-19 (aka Coronavirus) has obviously been a hot topic recently, especially within the media. But how dangerous is this new virus?

    The Covid-19 #Coronavirus Infographic Data Pack on Information is Beautiful gathers the current data around the world (version above is from March 31, 2020) and makes the virus more tangible to understand. The infographic makes comparisons to other diseases when it comes to incubation times and number of deaths, as well as reporting who is dying from it.

    Created by David McCandlessOmid KashanFabio BergamaschiDr Stephanie StarlingUnivers Labs

    From Information Is Beautiful:

    We made an infographic of the best COVID-19 / Coronavirus charts floating around, plus some of our own – all with the latest data

    We’ll plan to keep it updated every few days.

    They have also made all of their data accessible with a Google Sheet link: bit.ly/COVID19-DATA

    With so many good and bad COVID-19 charts being published at a frantic pace, I can appreciate the design and effort here to gather some of the best data and the best visualizations together in one place.




    1

    Humanity ‘Sleepwalking Towards the Edge of a Cliff’: 60% of Earth’s Wildlife Wiped Out Since 1970

    By Julia Conley Common Dreams “Nature is not a ‘nice to have’—it is our life-support system.” Scientists from around the world issued a stark warning to humanity Tuesday in a semi-annual report on the Earth’s declining biodiversity, which shows that … Continue reading




    1

    ‘Coming Mass Extinction’ Caused by Human Destruction Could Wipe Out 1 Million Species, Warns UN Draft Report

    By Jessica Corbett Common Dreams Far-reaching global assessment details how humanity is undermining the very foundations of the natural world     On the heels of an Earth Day that featured calls for radical action to address the current “age … Continue reading




    1

    Finnish Air Force FA-18C Hornet

    Andrew Rickmann posted a photo:




    1

    Finnish Air Force FA-18C Hornet

    Andrew Rickmann posted a photo:




    1

    Humanity ‘Sleepwalking Towards the Edge of a Cliff’: 60% of Earth’s Wildlife Wiped Out Since 1970

    By Julia Conley Common Dreams “Nature is not a ‘nice to have’—it is our life-support system.” Scientists from around the world issued a stark warning to humanity Tuesday in a semi-annual report on the Earth’s declining biodiversity, which shows that … Continue reading




    1

    ‘Coming Mass Extinction’ Caused by Human Destruction Could Wipe Out 1 Million Species, Warns UN Draft Report

    By Jessica Corbett Common Dreams Far-reaching global assessment details how humanity is undermining the very foundations of the natural world     On the heels of an Earth Day that featured calls for radical action to address the current “age … Continue reading




    1

    10 diagrams to help you think straight about UX Research

    Some of the problems we work on as UX researchers are simple and are easily solved by getting users in front of our product. But other problems can be complex and it's hard to know how to start solving them. In situations like that, a simple 2x2 diagram can cut through the 'what ifs', the 'how abouts' and the edge cases and provide a simple way of looking at the problem. Here are 10 examples of 2x2 diagrams to simplify UX research discussions.




    1

    12 symptoms of a back-to-front design process

    Everyday consumer products continue to frustrate people. The failure of companies to fully embrace UX is partly to blame, but there is also another reason -- one that is seldom discussed. Consumer product companies pay too much heed to their retail customers and, in so doing, they prevent the development team from getting first-hand knowledge of end users.




    1

    Talking to computers (part 1): Why is speech recognition so difficult?

    Although the performance of today's speech recognition systems is impressive, the experience for many is still one of errors, corrections, frustration and abandoning speech in favour of alternative interaction methods. We take a closer look at speech and find out why speech recognition is so difficult.




    1

    10 Design Principles to Reduce Cognitive Load

    If you’re not familiar with cognitive load and how it impacts interface design, it’s worth reviewing our previous blog post. If you’re already convinced cognitive load is important, the next step is addressing it. Reducing cognitive load is accomplished by reducing or offloading mental effort (which are similar but different concepts.) Reducing mental effort is […]

    The post 10 Design Principles to Reduce Cognitive Load appeared first on Psychology of Web Design | 3.7 Blog.




    1

    10 Ways to Get More From Your Website in 2020

    It’s a new year, a time of reflection and goal setting. Whether you subscribe to new years resolutions or not, 2020 should be the year you stop neglecting your website. Regardless of how performant your website currently is, it can be do better. You might already know this. You probably realize you should dedicate more […]

    The post 10 Ways to Get More From Your Website in 2020 appeared first on Psychology of Web Design | 3.7 Blog.




    1

    Alaska 2018

    For this years fishing trip to Alaska, I opted to upgrade my GoPro to a Panasonic GH-5 with Leica 12-60mm lense package at the local Best Buy. This would then accompany the Mavic drone footage. We had a couple sunny days for flying the drone, but really surprised how good the GH-5 footage turned out […]




    1

    Canada 2019

    The yearly fishing trip, this year at the Bulkley river in British Columbia. Shot on the Panasonic GH-5, DJI Mavic 2 Zoom and some GoPro.




    1

    10 Best Restaurant Menu Plugins for WordPress (Compared)

    Want to add a food menu to your restaurant website? Publishing your restaurant menu on your website comes in handy especially if you’re providing an online restaurant reservation or online food delivery. That way your users can figure out the available food options without having to walk into your restaurant. In this article, we’ll show […]

    The post 10 Best Restaurant Menu Plugins for WordPress (Compared) appeared first on IsItWP - Free WordPress Theme Detector.




    1

    12 Best GoDaddy Alternatives for Domain & Web Hosting (2020)

    Are you looking for the best GoDaddy alternative for domain registration and web hosting? Without a doubt, Godaddy is one of the most popular names when it comes to registering domain names and hosting your business online. Over the last 22 years, GoDaddy has managed to establish a stronghold in the market. In this article, […]

    The post 12 Best GoDaddy Alternatives for Domain & Web Hosting (2020) appeared first on IsItWP - Free WordPress Theme Detector.




    1

    10 On-Page SEO Factors You Should Consider [2019]

    When you want to succeed in the organic search engine results today, you have to focus on your website and learn what you should do to optimize it. There are many factors that can help you with that, form the technical, off-page, and on-page. All these factors and parts of a website require updating and […]

    Original post: 10 On-Page SEO Factors You Should Consider [2019]

    The post 10 On-Page SEO Factors You Should Consider [2019] appeared first on Daily Blog Tips.




    1

    Website Inspiration: Barrel Recap 2019

    Fun Annual Report One Pager (built using Webflow) by Barrel recapping their 2019 year. It’s busting with flavor from colorful changing backgrounds, cheeky thick-line illustrations and the playful bouncing social media icon footer. Also worth a shout is the responsive design, scaling up perfectly on huge screens while rearranging content well on small. Full Review




    1

    Mysterious Sharks Dance Away Bethel's COVID-19 Blues

    A couple of mysterious sharks have caught the fancy of the town. Maybe it's the cabin fever finally setting in, or perhaps this is what happens when you go too long without washing your mask, but Bethelites are going wild for two people in inflatable shark suits who pop up randomly around town.




    1

    More Than 1,000 Workers at Tyson Plant Have Coronavirus

    More than 1,000 workers at the Tyson Foods plant in Waterloo have tested positive for the coronavirus, a county public health leader said Thursday -- more than double the number Gov. Kim Reynolds had said were infected the day before.




    1

    Roy Horn of 'Siegfried and Roy' Dies of COVID-19 Complications

    Roy Horn, famed tiger handler and co-star of the magic duo known as Siegfried and Roy, died of complications from the coronavirus in a hospital in Las Vegas on Friday. He was 75 years old. "Today, the world has lost one of the greats of magic, but I have lost my best friend," Siegfried Fischbacher said in a statement. "From the moment we met, I knew Roy and I, together, would change the world." "There could be no Siegfried without Roy, and no Roy without Siegfried." This is a developing story. Please check back for updates.




    1

    DHS: Secret Service has 11 Current Virus Cases

    According to the DHS document, along with the 11 active cases there are 23 members of the Secret Service who have recovered from COVID-19 and an additional 60 employees who are self-quarantining. No details have been provided about which members of the Secret Service are infected or if any have recently been on detail with the president or vice president.




    1

    My Favorite Gifts For Photographers Under $100(ish)

    Every holiday season, I get an influx of DMs, tweets, texts and messages from followers, friends and family asking for my photo gear recommendations. This year, rather than putting together a list of all the high-tech cameras and lenses that come with high-price tags to match – I wanted share some affordable add-ons that thrifty photographers should have in their arsenal. As I like to say, the best camera is the one you have with you and most of the time that’s the one in your pocket ????  If you are looking for gift ideas for the photographer on your list these are my go-tos under $100(ish).   Moment Lens  These pocket size lenses will transform your mobile device into a lightweight DSLR. With a variety of lenses from fisheye to macro, Moment add-ons are durable, easy-to-use and have incredible clarity. Compatible with almost every smartphone, these compact lens take the camera in your pocket up a notch.          Shure Mic Shure has transformed mobile audio with its line of mobile mics. Regardless of your price point, the audio company creates options that will take your sound from distorted to crystal clear. As a photographer and podcaster […]

    The post My Favorite Gifts For Photographers Under $100(ish) appeared first on Chase Jarvis Photography.




    1

    10 Breaths Back to Love with Kamal Ravikant

    Kamal Ravikant was in a dark place. After four years of pouring his heart, soul, and money into his tech startup, it blew up. He lost everything – including himself. In a moment of desperation, a vow deep within came to the surface: to love himself. Though it was a bit of a foreign concept, he set out to undo the misery in his head through the lens of love. The practice Kamal formed became the self-published book: Love Yourself Like Your Life Depends on It. It sold over a half a million copies and is now newly expanded. In our conversation Kamal shares his ruthlessly practical way he unwound the negative thoughts and more importantly, made it last. In our conversation we explore: Mindset as a practice, including the 7 minute meditation Kamal uses to break old mental patterns Kamal shares his advice in getting unstuck, including giving yourself time to simply live Our brain is a monkey gone bananas. Pain, joy, loneliness, love are a universal part of the human condition such that no matter our individual circumstance we are all trying to tame it. and much more… Enjoy! FOLLOW KAMAL: instagram | twitter | website Listen to the Podcast […]

    The post 10 Breaths Back to Love with Kamal Ravikant appeared first on Chase Jarvis Photography.




    1

    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

    1

    Committed to the wrong branch? -, @{upstream}, and @{-1} to the rescue

    I get into this situation sometimes. Maybe you do too. I merge feature work into a branch used to collect features, and then continue development but on that branch instead of back on the feature branch

    git checkout feature
    # ... bunch of feature commits ...
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit feature
    git push
    # deploy qa-environment to the QA remote environment
    # ... more feature commits ...
    # oh. I'm not committing in the feature branch like I should be

    and have to move those commits to the feature branch they belong in and take them out of the throwaway accumulator branch

    git checkout feature
    git cherry-pick origin/qa-environment..qa-environment
    git push
    git checkout qa-environment
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit feature
    git checkout feature
    # ready for more feature commits

    Maybe you prefer

    git branch -D qa-environment
    git checkout qa-environment

    over

    git checkout qa-environment
    git reset --hard origin/qa-environment

    Either way, that works. But it'd be nicer if we didn't have to type or even remember the branches' names and the remote's name. They are what is keeping this from being a context-independent string of commands you run any time this mistake happens. That's what we're going to solve here.

    Shorthands for longevity

    I like to use all possible natively supported shorthands. There are two broad motivations for that.

    1. Fingers have a limited number of movements in them. Save as many as possible left late in life.
    2. Current research suggests that multitasking has detrimental effects on memory. Development tends to be very heavy on multitasking. Maybe relieving some of the pressure on quick-access short term memory (like knowing all relevant branch names) add up to leave a healthier memory down the line.

    First up for our scenario: the - shorthand, which refers to the previously checked out branch. There are a few places we can't use it, but it helps a lot:

    Bash
    # USING -
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit -        # ????
    git push
    # hack hack hack
    # whoops
    git checkout -        # now on feature ???? 
    git cherry-pick origin/qa-environment..qa-environment
    git push
    git checkout - # now on qa-environment ????
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit -        # ????
    git checkout -                       # ????
    # on feature and ready for more feature commits
    Bash
    # ORIGINAL
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit feature
    git push
    # hack hack hack
    # whoops
    git checkout feature
    git cherry-pick origin/qa-environment..qa-environment
    git push
    git checkout qa-environment
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit feature
    git checkout feature
    # ready for more feature commits

    We cannot use - when cherry-picking a range

    > git cherry-pick origin/-..-
    fatal: bad revision 'origin/-..-'
    
    > git cherry-pick origin/qa-environment..-
    fatal: bad revision 'origin/qa-environment..-'

    and even if we could we'd still have provide the remote's name (here, origin).

    That shorthand doesn't apply in the later reset --hard command, and we cannot use it in the branch -D && checkout approach either. branch -D does not support the - shorthand and once the branch is deleted checkout can't reach it with -:

    # assuming that branch-a has an upstream origin/branch-a
    > git checkout branch-a
    > git checkout branch-b
    > git checkout -
    > git branch -D -
    error: branch '-' not found.
    > git branch -D branch-a
    > git checkout -
    error: pathspec '-' did not match any file(s) known to git

    So we have to remember the remote's name (we know it's origin because we are devoting memory space to knowing that this isn't one of those times it's something else), the remote tracking branch's name, the local branch's name, and we're typing those all out. No good! Let's figure out some shorthands.

    @{-<n>} is hard to say but easy to fall in love with

    We can do a little better by using @{-<n>} (you'll also sometimes see it referred to be the older @{-N}). It is a special construct for referring to the nth previously checked out ref.

    > git checkout branch-a
    > git checkout branch-b
    > git rev-parse --abbrev-rev @{-1} # the name of the previously checked out branch
    branch-a
    > git checkout branch-c
    > git rev-parse --abbrev-rev @{-2} # the name of branch checked out before the previously checked out one
    branch-a

    Back in our scenario, we're on qa-environment, we switch to feature, and then want to refer to qa-environment. That's @{-1}! So instead of

    git cherry-pick origin/qa-environment..qa-environment

    We can do

    git cherry-pick origin/qa-environment..@{-1}

    Here's where we are (🎉 marks wins from -, 💥 marks the win from @{-1})

    Bash
    # USING - AND @{-1}
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit -                # ????
    git push
    # hack hack hack
    # whoops
    git checkout -                               # ????
    git cherry-pick origin/qa-environment..@{-1} # ????
    git push
    git checkout -                               # ????
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit -                # ????
    git checkout -                               # ????
    # ready for more feature commits
    Bash
    # ORIGINAL
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit feature
    git push
    # hack hack hack
    # whoops
    git checkout feature
    git cherry-pick origin/qa-environment..qa-environment
    git push
    git checkout qa-environment
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit feature
    git checkout feature
    # ready for more feature commits

    One down, two to go: we're still relying on memory for the remote's name and the remote branch's name and we're still typing both out in full. Can we replace those with generic shorthands?

    @{-1} is the ref itself, not the ref's name, we can't do

    > git cherry-pick origin/@{-1}..@{-1}
    origin/@{-1}
    fatal: ambiguous argument 'origin/@{-1}': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'

    because there is no branch origin/@{-1}. For the same reason, @{-1} does not give us a generalized shorthand for the scenario's later git reset --hard origin/qa-environment command.

    But good news!

    Do @{u} @{push}

    @{upstream} or its shorthand @{u} is the remote branch a that would be pulled from if git pull were run. @{push} is the remote branch that would be pushed to if git push was run.

    > git checkout branch-a
    Switched to branch 'branch-a'
    Your branch is ahead of 'origin/branch-a' by 3 commits.
      (use "git push" to publish your local commits)
    > git reset --hard origin/branch-a
    HEAD is now at <the SHA origin/branch-a is at>

    we can

    > git checkout branch-a
    Switched to branch 'branch-a'
    Your branch is ahead of 'origin/branch-a' by 3 commits.
      (use "git push" to publish your local commits)
    > git reset --hard @{u}                                # <-- So Cool!
    HEAD is now at <the SHA origin/branch-a is at>

    Tacking either onto a branch name will give that branch's @{upstream} or @{push}. For example

    git checkout branch-a@{u}

    is the branch branch-a pulls from.

    In the common workflow where a branch pulls from and pushes to the same branch, @{upstream} and @{push} will be the same, leaving @{u} as preferable for its terseness. @{push} shines in triangular workflows where you pull from one remote and push to another (see the external links below).

    Going back to our scenario, it means short, portable commands with a minimum human memory footprint. (🎉 marks wins from -, 💥 marks the win from @{-1}, 😎 marks the wins from @{u}.)

    Bash
    # USING - AND @{-1} AND @{u}
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit -    # ????
    git push
    # hack hack hack
    # whoops
    git checkout -                   # ????
    git cherry-pick @{-1}@{u}..@{-1} # ????????
    git push
    git checkout -                   # ????
    git reset --hard @{u}            # ????
    git merge --no-ff --no-edit -    # ????
    git checkout -                   # ????
    # ready for more feature commits
    Bash
    # ORIGINAL
    
    git checkout feature
    # hack hack hack
    git push
    git checkout qa-environment
    git merge --no-ff --no-edit feature
    git push
    # hack hack hack
    # whoops
    git checkout feature
    git cherry-pick origin/qa-environment..qa-environment
    git push
    git checkout qa-environment
    git reset --hard origin/qa-environment
    git merge --no-ff --no-edit feature
    git checkout feature
    # ready for more feature commits

    Make the things you repeat the easiest to do

    Because these commands are generalized, we can run some series of them once, maybe

    git checkout - && git reset --hard @{u} && git checkout -

    or

    git checkout - && git cherry-pick @{-1}@{u}.. @{-1} && git checkout - && git reset --hard @{u} && git checkout -

    and then those will be in the shell history just waiting to be retrieved and run again the next time, whether with CtrlR incremental search or history substring searching bound to the up arrow or however your interactive shell is configured. Or make it an alias, or even better an abbreviation if your interactive shell supports them. Save the body wear and tear, give memory a break, and level up in Git.

    And keep going

    The GitHub blog has a good primer on triangular workflows and how they can polish your process of contributing to external projects.

    The FreeBSD Wiki has a more in-depth article on triangular workflow process (though it doesn't know about @{push} and @{upstream}).

    The construct @{-<n>} and the suffixes @{push} and @{upstream} are all part of the gitrevisions spec. Direct links to each:



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

      1

      A Viget Glossary: What We Mean and Why it Matters - Part 1

      Viget has helped organizations design and develop award-winning websites and digital products for 20 years. In that time, we’ve been lucky to create long-term relationships with clients like Puma, the World Wildlife Fund, and Privia Health, and, throughout our time working together, we’ve come to understand each others’ unique terminology. But that isn’t always the case when we begin work with new clients, and in a constantly-evolving industry, we know that new terminology appears almost daily and organizations have unique definitions for deliverables and processes.

      Kicking off a project always initiates a flurry of activity. There are contracts to sign, team members to introduce, and new platforms to learn. It’s an exciting time, and we know clients are anxious to get underway. Amidst all the activity, though, there is a need to define and create a shared lexicon to ensure both teams understand the project deliverables and process that will take us from kickoff to launch.

      Below, we’ve rounded up a few terms for each of our disciplines that often require additional explanation. Note: our definitions of these terms may differ slightly from the industry standard, but highlight our interpretation and use of them on a daily basis.

      User Experience

      Research

      In UX, there is a proliferation of terms that are often used interchangeably and mean almost-but-subtly-not the same thing. Viget uses the term research to specifically mean user research — learning more about the users of our products, particularly how they think and behave — in order to make stronger recommendations and better designs. This can be accomplished through different methodologies, depending on the needs of the project, and can include moderated usability testing, stakeholder interviews, audience research, surveys, and more. Learn more about the subtleties of UX research vocabulary in our post on “Speaking the Same Language About Research”.

      Wireframes

      We use wireframes to show the priority and organization of content on the screen, to give a sense of what elements will get a stronger visual treatment, and to detail how users will get to other parts of the site. Wireframes are a key component of website design — think of them as the skeleton or blueprint of a page — but we know that clients often feel uninspired after reviewing pages built with gray boxes. In fact, we’ve even written about how to improve wireframe presentations. We remind clients that visual designers will step in later to add polish through color, graphics, and typography, but agreeing on the foundation of the page is an important and necessary first step.

      Prototypes

      During the design process, it’s helpful for us to show clients how certain pieces of functionality or animations will work once the site is developed. We can mimic interactivity or test a technical proof of concept by using a clickable prototype, relying on tools like Figma, Invision, or Principle. Our prototypes can be used to illustrate a concept to internal stakeholders, but shouldn’t be seen as a final approach. Often, these concepts will require additional work to prepare them for developer handoff, which means that prototypes quickly become outdated. Read more about how and when we use prototypes.

      Navigation Testing (Treejack Testing)

      Following an information architecture presentation, we will sometimes recommend that clients conduct navigation testing. When testing, we present a participant with the proposed navigation and ask them to perform specific tasks in order to see if they will be able to locate the information specified within the site’s new organization. These tests generally focus on two aspects of the navigation: the structure of the navigation system itself, and the language used within the system. Treejack is an online navigation testing tool that we like to employ when conducting navigation tests, so we’ll often interchange the terms “navigation testing” with “treejack testing”.

      Learn more about Viget’s approach to user experience and research




      1

      5 things to Note in a New Phoenix 1.5 App

      Yesterday (Apr 22, 2020) Phoenix 1.5 was officially released ????

      There’s a long list of changes and improvements, but the big feature is better integration with LiveView. I’ve previously written about why LiveView interests me, so I was quite excited to dive into this release. After watching this awesome Twitter clone in 15 minutes demo from Chris McCord, I had to try out some of the new features. I generated a new phoenix app with the —live flag, installed dependencies and started a server. Here are five new features I noticed.

      1. Database actions in browser

      Oops! Looks like I forgot to configure the database before starting the server. There’s now a helpful message and a button in the browser that can run the command for me. There’s a similar button when migrations are pending. This is a really smooth UX to fix a very common error while developing.

      2. New Tagline!

      Peace-of-mind from prototype to production

      This phrase looked unfamiliar, so I went digging. Turns out that the old tagline was “A productive web framework that does not compromise speed or maintainability.” (I also noticed that it was previously “speed and maintainability” until this PR from 2019 was opened on a dare to clarify the language.)

      Chris McCord updated the language while adding phx.new —live. I love this framing, particularly for LiveView. I am very excited about the progressive enhancement path for LiveView apps. A project can start out with regular, server rendered HTML templates. This is a very productive way to work, and a great way to start a prototype for just about any website. Updating those templates to work with LiveView is an easier lift than a full rebuild in React. And finally, when you’re in production you have the peace-of-mind that the reliable BEAM provides.

      3. Live dependency search

      There’s now a big search bar right in the middle of the page. You can search through the dependencies in your app and navigate to the hexdocs for them. This doesn’t seem terribly useful, but is a cool demo of LiveView. The implementation is a good illustration of how compact a feature like this can be using LiveView.

      4. LiveDashboard

      This is the really cool one. In the top right of that page you see a link to LiveDashboard. Clicking it will take you to a page that looks like this.

      This page is built with LiveView, and gives you a ton of information about your running system. This landing page has version numbers, memory usage, and atom count.

      Clicking over to metrics brings you to this page.

      By default it will tell you how long average queries are taking, but the metrics are configurable so you can define your own custom telemetry options.

      The other tabs include process info, so you can monitor specific processes in your system:

      And ETS tables, the in memory storage that many apps use for caching:

      The dashboard is a really nice thing to get out of the box and makes it free for application developers to monitor their running system. It’s also developing very quickly. I tried an earlier version a week ago which didn’t support ETS tables, ports or sockets. I made a note to look into adding them, but it's already done! I’m excited to follow along and see where this project goes.

      5. New LiveView generators

      1.5 introduces a new generator mix phx.gen.live.. Like other generators, it will create all the code you need for a basic resource in your app, including the LiveView modules. The interesting part here is that it introduces patterns for organizing LiveView code, which is something I have previously been unsure about. At first glance, the new organization makes sense and feels like a good approach. I look forward to seeing how this works on a real project.

      Conclusion

      The 1.5 release brings more changes under the hood of course, but these are the first five differences you’ll notice after generating a new Phoenix 1.5 app with LiveView. Congratulations to the entire Phoenix team, but particularly José Valim and Chris McCord for getting this work released.



      • Code
      • Back-end Engineering

      1

      10 Cool & Free Mobile Wallpapers

      Guys, great news! Our friends at Freepik has released exclusively for s2o readers 10 Cool & Free Mobile Wallpapers in several awesome styles. They come in AI, EPS and jpg files. The wallpapers are easily resizable for any kind of mobile —or any other project ;)— so you can adapt them in a no time …

      10 Cool & Free Mobile Wallpapers Read More »




      1

      Cute Collection of 210 User Interface Icons

      Did you remember how was your life before Freepik and Flaticon. No I can’t remember the dark ages either. To celebrate this golden times, they are giving away once more an incredible package of 210 User Interface Icons in 3 versions: Flat, filled and lineal.  Download This work is licensed under a Creative Commons Attribution 3.0 License …

      Cute Collection of 210 User Interface Icons Read More »