Lessons Learned While Developing WordPress Plugins

Lessons Learned While Developing WordPress Plugins

Lessons Learned While Developing WordPress Plugins

Jakub Mikita

2018-05-24T13:30:28+02:00
2018-05-24T12:27:17+00:00

Every WordPress plugin developer struggles with tough problems and code that’s difficult to maintain. We spend late nights supporting our users and tear out our hair when an upgrade breaks our plugin. Let me show you how to make it easier.

In this article, I’ll share my five years of experience developing WordPress plugins. The first plugin I wrote was a simple marketing plugin. It displayed a call to action (CTA) button with Google’s search phrase. Since then, I’ve written another 11 free plugins, and I maintain almost all of them. I’ve written around 40 plugins for my clients, from really small ones to one that have been maintained for over a year now.

Measuring Performance With Heatmaps

Heatmaps can show you the exact spots that receive the most engagement on a given page. Find out why they’re so efficient for your marketing goals and how they can be integrated with your WordPress site. Read article →

Good development and support lead to more downloads. More downloads mean more money and a better reputation. This article will show you the lessons I’ve learned and the mistakes I’ve made, so that you can improve your plugin development.

1. Solve A Problem

If your plugin doesn’t solve a problem, it won’t get downloaded. It’s as simple as that.

Take the Advanced Cron Manager plugin (8,000+ active installations). It helps WordPress users who are having a hard time debugging their cron. The plugin was written out of a need — I needed something to help myself. I didn’t need to market this one, because people already needed it. It scratched their itch.

On the other hand, there’s the Bug — fly on the screen plugin (70+ active installations). It randomly simulates a fly on the screen. It doesn’t really solve a problem, so it’s not going to have a huge audience. It was a fun plugin to develop, though.

Focus on a problem. When people don’t see their SEO performing well, they install an SEO plugin. When people want to speed up their website, they install a caching plugin. When people can’t find a solution to their problem, then they find a developer who writes a solution for them.

As David Hehenberger attests in his article about writing a successful plugin, need is a key factor in the WordPress user’s decision of whether to install a particular plugin.

If you have an opportunity to solve someone’s problem, take a chance.

2. Support Your Product

“3 out of 5 Americans would try a new brand or company for a better service experience. 7 out of 10 said they were willing to spend more with companies they believe provide excellent service.”

— Nykki Yeager

Don’t neglect your support. Don’t treat it like a must, but more like an opportunity.

Good-quality support is critical in order for your plugin to grow. Even a plugin with the best code will get some support tickets. The more people who use your plugin, the more tickets you’ll get. A better user experience will get you fewer tickets, but you will never reach inbox 0.

Every time someone posts a message in a support forum, I get an email notification immediately, and I respond as soon as I can. It pays off. The vast majority of my good reviews were earned because of the support. This is a side effect: Good support often translates to 5-star reviews.

When you provide excellent support, people start to trust you and your product. And a plugin is a product, even if it’s completely free and open-source.

Good support is more complex than about writing a short answer once a day. When your plugin gains traction, you’ll get several tickets per day. It’s a lot easier to manage if you’re proactive and answer customers’ questions before they even ask.

Here’s a list of some actions you can take:

  • Create an FAQ section in your repository.
  • Pin the “Before you ask” thread at the top of your support forum, highlighting the troubleshooting tips and FAQ.
  • Make sure your plugin is simple to use and that users know what they should do after they install it. UX is important.
  • Analyze the support questions and fix the pain points. Set up a board where people can vote for the features they want.
  • Create a video showing how the plugin works, and add it to your plugin’s main page in the WordPress.org repository.

It doesn’t really matter what software you use to support your product. The WordPress.org’s official support forum works just as well as email or your own support system. I use WordPress.org’s forum for the free plugins and my own system for the premium plugins.

3. Don’t Use Composer

Composer is package-manager software. A repository of packages is hosted on packagist.org, and you can easily download them to your project. It’s like NPM or Bower for PHP. Managing your third-party packages the way Composer does is a good practice, but don’t use it in your WordPress project.

I know, I dropped a bomb. Let me explain.

Composer is great software. I use it myself, but not in public WordPress projects. The problem lies in conflicts. WordPress doesn’t have any global package manager, so each and every plugin has to load dependencies of their own. When two plugins load the same dependency, it causes a fatal error.

There isn’t really an ideal solution to this problem, but Composer makes it worse. You can bundle the dependency in your source manually and always check whether you are safe to load it.

Composer’s issue with WordPress plugins is still not solved, and there won’t be any viable solution to this problem in the near future. The problem was raised many years ago, and, as you can read in WP Tavern’s article, many developers are trying to solve it, without any luck.

The best you can do is to make sure that the conditions and environment are good to run your code.

4. Reasonably Support Old PHP Versions

Don’t support very old versions of PHP, like 5.2. The security issues and maintenance aren’t worth it, and you’re not going to earn more installations from those older versions.

The Notification plugin’s usage on PHP versions from May 2018. (Large preview)

Go with PHP 5.6 as a minimal requirement, even though official support will be dropped by the end of 2018. WordPress itself requires PHP 7.2.

There’s a movement that discourages support of legacy PHP versions. The Yoast team released the Whip library, which you can include in your plugin and which displays to your users important information about their PHP version and why they should upgrade.

Tell your users which versions you do support, and make sure their website doesn’t break after your plugin is installed on too low a version.

5. Focus On Quality Code

Writing good code is tough in the beginning. It takes time to learn the “SOLID” principles and design patterns and to change old coding habits.

It once took me three days to display a simple string in WordPress, when I decided to rewrite one of my plugins using better coding practices. It was frustrating knowing that it should have taken 30 minutes. Switching my mindset was painful but worth it.


Source: Smashing Magazine

Top Angular Plugins for Sublime Text

This article covers a number of Angular plugins for the Sublime Text text editor.

Whether you’re new to Angular (version 2+) development, and looking to get started with it and integrate it more closely with your code editor of choice, or you’re an old hand at Angular development and you’re trying your hand with Sublime Text as a new editor, integrating the two has never been easier.

There are lots of options for Angular plugins that can smooth your way developing Angular apps using Sublime Text. You’ll need to set up the Sublime Text package manager (called “Package Control”) prior to getting started, and then you can take a look at the list of plugins here and see if any meet your needs!

Setting up Package Control

In order to use most of the Angular plugins that will be discussed in this article, you’ll first need to set up Package Control in Sublime Text. This is a fairly painless process. The easiest way involves copy-pasting a configuration code.

  1. Use the hotkey CTRL + ` or use the View > Show Console menu to bring up the integrated Sublime Text console.
  2. Paste the block of Python code into the console, which can be copied from the Package Control Installation page and follow the instructions there.
  3. Once this is done, the Package Control menus will be set up! Now, all you’ll need to do is find and install your packages.

Installing a Sublime Text Package via Package Control Menus

Using Package Control is a breeze. You’ll need to open Package Control, select the install menu, and then choose and install a package:

  1. Use the shortcut CMD + Shift + P (CTRL + Shift + P, depending on OS) to open the command palette.
  2. Type install package and then press Enter, which brings you to the list of available packages.
  3. Search for the package by name, select the package, then press Enter to install.

Angular 2 HTML Package

The Angular 2 HTML plugin provides augmented HTML syntax for Sublime Text. You’ll be able to use Angular attributes without syntax highlighting being broken. Additionally, the JavaScript parts of your pages will also highlight as JavaScript. A small but incredibly useful addition for Angular developers.

Angular 2 HTML Package Setup

At the time of this writing, this plugin was not present in Package Control, but can be installed manually via the following steps.

  1. Close Sublime Text and navigate via the Command Line to your Sublime Text 3 “Packages” folder in your application installation. In macOS, this is at /Users/{user}/Library/Application Support/Sublime Text 3/Packages.

  2. Clone the repository into your Packages folder with the following:

    git clone https://github.com/princemaple/ngx-html-syntax
    
  3. Re-open Sublime Text 3, and check in the View > Syntax menu to ensure that Ngx HTML is an option.

Additionally, you can have Sublime Text automatically highlight .component.html files with Angular 2 HTML Syntax:

  1. Open a .component.html file.

  2. Choose View > Syntax > Ngx HTML.

  3. Go to Preferences > Settings > Syntax Specific. Because your current file is using the Ngx HTML syntax, it should open the syntax-specific settings file for Ngx HTML. If so, add an extensions entry to the settings panel on the right:

    "extensions":
    [
      "component.html"
    ]
    
  4. Restart Sublime Text. Now, all .component.html files should automatically use the Ngx Syntax plugin!

Continue reading %Top Angular Plugins for Sublime Text%


Source: Sitepoint

Descriptive Analytics vs Diagnostic Analytics

Recently, David Attard wrote about analytics and KPIs (key performance indicators), and how they can be used to understand our website users better — and, in turn, to help us design better experiences for those users. He told us about the important metrics to analyze (time on site, bounce rate, conversions, exit rates, etc.), but also mentioned that, while these metrics help us to understand what users are doing (or not doing) on our website, the reasons why can still be a bit of a blur. This is because, while data is objective, the conclusions drawn from it are often subjective.

Even though KPIs describe our users’ behavior, more context is needed to draw solid conclusions about the state of our UX. In order for this to happen, we have to use other techniques — such as A/B testing and usability testing — to diagnose the UX flaws we identify through descriptive analytics. In this article, I’m going to explain the difference between descriptive analytics and diagnostic analytics, so that you have a realistic expectation of what descriptive analytics can do, and what you’ll need to gain from descriptive analytics before you begin A/B testing and usability testing.

Descriptive Analytics

Descriptive analytics in a nutshell: what has happened?

When you visit a nurse or doctor, it’s because you have undesirable symptoms that indicate bad health. You have trouble doing the things you need to do because of this. You don’t know what’s going on exactly, only that you aren’t functioning at an optimal level. This is likened to analytics, where business goals can’t be met because of bad user experience. Certain KPIs might indicate this, such as high bounce rate or low Avg. Time on Site.

KPIs describe the symptoms, but they don’t actually diagnose what the underlying issue is, and this is why we call them descriptive analytics. However, we can use the symptoms to help diagnose the UX flaws.

We can use tools like Kissmetrics to track and analyze KPIs, although many companies choose to use Google Analytics because it’s rather sophisticated for a free tool. As well as the KPIs mentioned in David’s article, analytics tools like Google Analytics can reliably tell us things about our users’ demographic and interests (that is, who they are and what they like), and also other important tidbits of information such as what device they’re using and where they’re from. This kind of data, even though it can’t be used to indicate website performance, can tell us a little more about the user intent.

Consider these descriptive analytics as background information that we can use to narrow down what’s going wrong exactly (i.e. user research).

Continue reading %Descriptive Analytics vs Diagnostic Analytics%


Source: Sitepoint

Ethereum Wallets: Send and Receive Ether with MyEtherWallet

In this article, we’ll go through the process of generating your first Ethereum wallet and sending and receiving ether through the MyEtherWallet interface.

For a better understanding of the information which follows, it’s recommended you read the following first:


There are many ways to interact with the Ethereum blockchain. In this piece, we’ll be using MyEtherWallet (MEW).

Note: After opening the site, please bookmark it so you never have to paste it into your browser again. There are many bad people who want your ether, and they’ve bought domains similar to the domain of this site hoping you’ll fall into that trap by mistyping!

Immediately after loading, the page will display some warnings about them not being a bank and basically not being able to help you if you lose your funds because they don’t have access to them. The gist of it is that you’re responsible for your own funds.

MEW initial screen

Creating and Reading an Address

The first screen of MEW is the “input password” screen. Input a password for a new wallet. (Make it something complex but easy to remember or use a password generator like LastPass.)

Password input

The address is immediately generated in the background, but MEW won’t let you see it yet. For as long as you haven’t saved the Keystore file somewhere safe, you cannot proceed. Click Download Keystore File (UTC / JSON) and store it on a USB drive, then hide it from curious family members. The file will be called something like UTC--2018-01-26T10-39-56.592Z--d877263725d9247352661e44c444b21dc5a28581. The first part is the date of creation, the second is the address itself. After you’ve stored it safely, the next screen will display the private key.

Private key

Very imporant!! The private key is equivalent in access level to the file you downloaded previously. Both can be imported into wallet software and used to unlock an address to spend money on it. But there is an important difference: the private key does not require a password! If you enter a private key into another tool like MetaMask, the address will immediately become unlocked without a password and can be used for sending Ether and tokens. If you import the previously downloaded file into any wallet software, it will require a password before letting you access it fully. Therefore, it’s safer to only keep one method around: either store the file and remember the password, or store only the private key in a very secure location. Destroy the other method. The fewer ways to access your wallet there are, the safer the money is.

You can generate a Paper Wallet on the same screen. This will open a new tab with a neatly generated printable layout of two QR codes. One is the public key — the address to which you can send funds and tokens — and the other is the private key mentioned above.

Paper Wallet

If you’re planning to use this address for long-term holding of ether, it’s smart to print it and store it in a safe as if you had a bond or a big wad of cash.

After these steps have been completed, MEW lets us unlock the wallet and view its info. This can be done in two ways:

  • Picking a Keystore/JSON file will provide you with a form through which you upload the file you downloaded previously. You’ll then be asked for a password.
  • Picking a private key lets you paste the private key directly into the field, unlocking the address for usage.

Unlock your wallet and you should see something like the image below:

Unlocked wallet info UI

This interface lets you print the wallet again if you lost or destroyed the previous one, or to re-download the JSON file if you lost it and accessed the wallet with the private key. The QR code for the private key can be read by clicking the eye icon under the black rectangle in the bottom of the screen.

Revealing the private key

On the right, you can see your account’s balance: 0 Eth. A little lower you can see the Token Balances frame which shows you how many of which tokens you have. Because of a large number of available tokens out there, you first need to click Show all tokens to load them.

This screen is visible because you’re on the View Wallet Info option to which MEW automatically redirects you after creation. When sending tokens or ether, the option to use is Send Ether and Tokens.

MEW UI options

Continue reading %Ethereum Wallets: Send and Receive Ether with MyEtherWallet%


Source: Sitepoint

Introduction to Popmotion: Pointers and Physics

Welcome back to the Introduction to Popmotion tutorial series. In part 1, we discovered how to use tweens and keyframes to make precise, time-scheduled animations.

In Part 2, we’re going to look at pointer tracking and velocity-based animations.

Pointer tracking allows us to create scrollable product shelves, custom value sliders, or drag-and-drop interfaces.

Velocity-based animations are different to a time-based animation like tween in that the primary property that affects how the animation behaves is velocity. The animation itself might take any amount of time.

We’ll look at the three velocity-based animations in Popmotion, springdecay, and physics. We’ll use the velocity of the pointer tracking animation to start these animations, and that’ll demonstrate how velocity-based animations can create engaging and playful UIs in a way that time-based animations simply can’t.

First, open this CodePen to play along.

Pointer Tracking

Popmotion provides the pointer function to track and output the coordinates of either a mouse or single touch pointer.

Let’s import this along with styler, which will allow us to set the position of the ball.

For this example, we want to drag the ball. Let’s add an event that will output the pointer’s position to the ball:

We’ll also want some code to stop tracking when we release the ball:

If you try and drag the ball now, there’s an obvious problem. The ball jumps away when we touch it! Not a great user experience.

This is because, by default, pointer outputs the pointer’s position relative to the page.

To output the pointer’s position relative to another point, in this case the ball’s x/y transform, we can simply pass that position to pointer like this:

Now you’ve made the ball, in very few lines of code, draggable! However, when the user releases the ball, it stops dead.

This isn’t satisfying: Imagine a scrollable carousel of products that a user can drag to scroll. If it just stopped dead instead of momentum scrolling, it’d be less pleasurable to use.

It’d be harder, too, because the overall physical effort needed to scroll the carousel would be higher.

To enable animations like this, we first need to know the velocity of the object being thrown.

Track Velocity

Popmotion provides a function that can help us track velocity. It’s called value. Let’s import that:

To speak technically for a moment, all of Popmotion’s animations are known as actions. Actions are reactive streams of values that can be started and stopped.

A value is, conversely, a reaction. It can’t be stopped or started. It just passively responds when its update method is called. It can keep track of values and can be used to query their velocity.

So, after we define ballStyler, let’s define a new value for ballXY:

Whenever ballXY updates, we want to update ballStyler. We can pass a second argument to value, a function that will run whenever ballXY updates:

Now we can rewrite our pointer to update ballXY instead of ballStyler.set:

Now, at any pointer, we can call ballXY.getVelocity() and we’ll receive the velocities of both x and y, ready to plug into our velocity-based animations.

Velocity-Based Animations

spring

The first velocity-based animation to introduce is spring. It’s based on the same equations that govern Apple’s CASpringAnimation, the spring animation behind all that iOS springy playfulness.

Import:

Now, amend stopTracking so that instead of stopping the pointerTracker animation, it starts a spring animation like this:

We provide it with the ball’s current position, its velocity, and a target, and the simulation is run. It changes depending on how the user has thrown the ball.

The cool thing about springs is they’re expressive. By adjusting the massstiffness and damping properties, you can end up with radically different spring-feels.

For instance, if you only change the stiffness above to 1000, you can create a motion that feels like high-energy snapping. Then, by changing mass to 20, you create motion that looks almost like gravity.

There’s a combination that will feel right and satisfying for your users, and appropriate to your brand, under almost any circumstance. By playing with different spring-feels, you can communicate different feelings, like a strict out-of-bounds snap or a softer affirmative bounce.

decay

The decay animation, as the name suggests, decays the provided velocity so that the animation gradually slows to a complete stop.

This can be used to create the momentum scrolling effect found on smartphones, like this:

Import the decay function:

And replace the stopTracking function with the following:

decay automatically calculates a new target based on the provided from and velocity props.

It’s possible to adjust the feel of the deceleration by messing with the props outlined in the docs linked above but, unlike spring and physicsdecay is designed to work out of the box. 

physics

Finally, we have the physics animation. This is Popmotion’s Swiss Army knife of velocity-based animations. With it, you can simulate:

  • constant velocity
  • acceleration
  • springs
  • friction

spring and decay offer super-precise motion and a wider variety of “feels”. Soon, they’ll both also be scrubbable.

But both are immutable. Once you’ve started either, their properties are set in stone. Perfect for when we want to start an animation based on the initial from/velocity state, but not so good if we want ongoing interaction.

physics, instead, is an integrated simulation closer to that of a video game. It works by, once per frame, taking the current state and then modifying it based on the current properties at that point in time.

This allows it to be mutable, which means we can change those properties, which then changes the outcome of the simulation.

To demonstrate this, let’s make a twist on classic pointer smoothing, with elastic smoothing.

Import physics:

This time, we’re going to change the startTracking function. Instead of changing ballXY with pointer, we’ll use physics:

Here, we’re setting from and velocity as normal. friction and springStrength both adjust the properties of the spring.

restSpeed: false overrides the default behaviour of the animation stopping when motion stops. We want to stop it manually in stopTracking.

On its own, this animation won’t do anything because we set to, the spring’s target, to the same as from. So let’s reimplement the pointer tracking this time to change the spring target of physics. On the last line of startTracking, add:

Here, we’re using a similar pointer animation as before. Except this time, we’re using it to change the target of another animation. In doing so, we create this elasticated pointer tracking:

Conclusion

Velocity-based animations paired with pointer tracking can create engaging and playful interfaces.

spring can be used to create a wide-variety of spring-feels, while decay is specifically tailored for momentum scroll animations. physics is more limited than either in terms of configurability, but also provides the opportunity to change the simulation in progress, opening new interaction possibilities.

In the next and final part of this introductory series on Popmotion, we’re going to take everything we’ve learned in the first two parts and use them along with some light functional composition to create a scrubbable animation, along with a scrubber to do the scrubbing with!


Source: Nettuts Web Development

Creating The Feature Queries Manager DevTools Extension

Creating The Feature Queries Manager DevTools Extension

Creating The Feature Queries Manager DevTools Extension

Ire Aderinokun

2018-05-23T12:00:00+02:00
2018-05-23T13:42:58+00:00

Within the past couple of years, several game-changing CSS features have been rolled out to the major browsers. CSS Grid Layout, for example, went from 0 to 80% global support within the span of a few months, making it an incredibly useful and reliable tool in our arsenal. Even though the current support for a feature like CSS Grid Layout is relatively great, not all recent or current browsers support it. This means it’s very likely that you and I will currently be developing for a browser in which it is not supported.

The modern solution to developing for both modern and legacy browsers is feature queries. They allow us to write CSS that is conditional on browser support for a particular feature. Although working with feature queries is almost magical, testing them can be a pain. Unlike media queries, we can’t easily simulate the different states by just resizing the browser. That’s where the Feature Queries Manager comes in, an extension to DevTools to help you easily toggle your feature query conditions. In this article, I will cover how I built this extension, as well as give an introduction to how developer tools extensions are built.

Working With Unsupported CSS

If a property-value pair (e.g. display: grid), is not supported by the browser the page is viewed in, not much happens. Unlike other programming languages, if something is broken or unsupported in CSS, it only affects the broken or unsupported rule, leaving everything else around it intact.

Let’s take, for example, this simple layout:

The layout in a supporting browser

Large preview

We have a header spanning across the top of the page, a main section directly below that to the left, a sidebar to the right, and a footer spanning across the bottom of the page.

Here’s how we could create this layout using CSS Grid:

See the Pen layout-grid by Ire Aderinokun (@ire) on CodePen.

In a supporting browser like Chrome, this works just as we want. But if we were to view this same page in a browser that doesn’t support CSS Grid Layout, this is what we would get:

The layout in an unsupporting browser

Large preview

It is essentially the same as if we had not applied any of the grid-related styles in the first place. This behavior of CSS was always intentional. In the CSS specification, it says:

In some cases, user agents must ignore part of an illegal style sheet, [which means to act] as if it had not been there

Historically, the best way to handle this has been to make use of the cascading nature of CSS. According to the specification, “the last declaration in document order wins.” This means that if there are multiple of the same property being defined within a single declaration block, the latter prevails.

For example, if we have the follow declarations:

body {
  display: flex;
  display: grid;
}

Assuming both Flexbox and Grid are supported in the browser, the latter — display: grid — will prevail. But if Grid is not supported by the browser, then that rule is ignored, and any previous valid and supported rules, in this case display: flex, are used instead.

body {
  display: flex;
  display: grid;
}

Cascading Problems

Using the cascade as a method for progressive enhancement is and has always been incredibly useful. Even today, there is no simpler or better way to handle simple one-liner fallbacks, such as this one for applying a solid colour where the rgba() syntax is not supported.

div {
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.5);
}

Using the cascade, however, has one major limitation, which comes into play when we have multiple, dependent CSS rules. Let’s again take the layout example. If we were to attempt to use this cascade technique to create a fallback, we would end up with competing CSS rules.

See the Pen layout-both by Ire Aderinokun (@ire) on CodePen.

In the fallback solution, we need to use certain properties such as margins and widths, that aren’t needed and in fact interfere with the “enhanced” Grid version. This makes it difficult to rely on the cascade for more complex progressive enhancement.

Feature Queries To The Rescue!


Source: Smashing Magazine

Developer Economics Survey: Your Chance to Win Prizes & Voice Opinions

This article was created in partnership with SlashData. Thank you for supporting the partners who make SitePoint possible.

Is JavaScript giving you headaches? Do you wish other developers knew how important Swift and Rust will be in the coming years? It’s your chance to turn your opinions into a tool of change! The new Developer Economics survey is open starting from April 30, calling out all software developers to take part. Start right away.

Don’t miss a chance to join over 40,000 developers from 160+ countries who take part in the Developer Economics surveys every year to tell the world where software development is going next.

Who can take the survey?

Pretty much everyone writing code and getting their hands on software development in Mobile, Desktop, IoT, AR/VR, Machine Learning & Data Science, Web, Backend and Games. It doesn’t matter if you’re a hobbyist, a startupper or an enterprise dev – the survey is open for all real developers out there!

What sort of questions are they asking?

The survey is designed to dive into real-life developer issues, from coding skills and favorite tools to satisfaction with learning resources and communities.

Expect questions like:

  • Which are your favorite tools and platforms?
  • What’s going up and what’s going down in the software industry?
  • Are you working on the projects you would like to work on?
  • Where do you think development time should be invested?

There are also deep-dive questions based on your area of expertise, like Machine Learning, IoT, web development and more where you can really show you’re a pro and answer more complex questions about your favorite frameworks and vendors.

Read to take the survey?

Why should you take the survey?

It’s fun, for starters! The survey is designed to reveal your sci-fi profile, so the more you engage, the closer you get to finding out your place in the galaxy far far away.

Then there’s prizes. This time, devs who take part and complete the survey can win stuff like iPhone X, Samsung S9 Plus, HTC Vive Pro, GitHub Developer Plan, Amazon vouchers and other useful things to help you test your work or just play around.

You can also take part in the referral program, which allows you to win up to $700 in cash by referring other developer friends to take the survey.

Last but not least, everyone who takes the survey will get a insights with key findings from the survey as well as free report with the highlights and up-and-coming trends.

If you have a few minutes to spare and want to have a quality time, then this survey is for perfect for you! You can start right here. Extra tip: if you need to take a break, just click to save your responses and then you can come back and continue where you left off.

Good luck!

Take the survey now!

Continue reading %Developer Economics Survey: Your Chance to Win Prizes & Voice Opinions%


Source: Sitepoint

Authenticating Firebase and Angular with Auth0: Part 2

This article was originally published on the Auth0.com blog, and is republished here with permission.

In this two-part tutorial series, we’ll learn how to build an application that secures a Node back end and an Angular front end with Auth0 authentication. Our server and app will also authenticate a Firebase Cloud Firestore database with custom tokens so that users can leave realtime comments in a secure manner after logging in with Auth0. The Angular application code can be found at the angular-firebase GitHub repo and the Node API can be found in the firebase-auth0-nodeserver repo.

The first part of our tutorial, Authenticating Firebase and Angular with Auth0: Part 1, covered:

  • intro and setup for Auth0 and Firebase
  • implementing a secure Node API that mints custom Firebase tokens and provides data for our app
  • Angular application architecture with modules and lazy loading
  • Angular authentication with Auth0 with service and route guard
  • shared Angular components and API service.

Authenticating Firebase and Angular with Auth0: Part 2

Part 2 of our tutorial will cover:

  1. Displaying Dogs: Async and NgIfElse
  2. Dog Details with Route Parameters
  3. Comment Model Class
  4. Firebase Cloud Firestore and Rules
  5. Comments Component
  6. Comment Form Component
  7. Realtime Comments
  8. Conclusion

Our completed app will look something like this:

Angular Firebase app with Auth0 custom tokens

Let’s pick up right where we left off at the end of Authenticating Firebase and Angular with Auth0: Part 1.

Displaying Dogs: Async and NgIfElse

Let’s implement the home page of our app — the dogs listing. We created the scaffolding for this component when we set up our Angular app’s architecture.

Important Note: Make sure your Node.js API is running. If you need a refresher on the API, refer to How to Authenticate Firebase and Angular with Auth0: Part 1 – Node API.

Dogs Component Class

Open the dogs.component.ts class file now and implement this code:

// src/app/dogs/dogs/dogs.component.ts
import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ApiService } from '../../core/api.service';
import { Dog } from './../../core/dog';
import { Observable } from 'rxjs/Observable';
import { tap, catchError } from 'rxjs/operators';

@Component({
  selector: 'app-dogs',
  templateUrl: './dogs.component.html'
})
export class DogsComponent implements OnInit {
  pageTitle = 'Popular Dogs';
  dogsList$: Observable<Dog[]>;
  loading = true;
  error: boolean;

  constructor(
    private title: Title,
    private api: ApiService
  ) {
    this.dogsList$ = api.getDogs$().pipe(
      tap(val => this._onNext(val)),
      catchError((err, caught) => this._onError(err, caught))
    );
  }

  ngOnInit() {
    this.title.setTitle(this.pageTitle);
  }

  private _onNext(val: Dog[]) {
    this.loading = false;
  }

  private _onError(err, caught): Observable<any> {
    this.loading = false;
    this.error = true;
    return Observable.throw('An error occurred fetching dogs data.');
  }

}

After our imports, we’ll set up some local properties:

  • pageTitle: to set our page’s <h1> and <title>
  • dogsList$: the observable returned by our API HTTP request to fetch the dogs listing data
  • loading: to show a loading icon while the API request is being made
  • error: to display an error if something goes wrong fetching data from the API.

We’re going to be using the declarative async pipe to respond to the dogsList$ observable returned by our API GET request. With the async pipe, we don’t need to subscribe or unsubscribe in our DogsComponent class: the subscription process will be managed automatically! We just need to set up our observable.

We’ll make Title and ApiService available to our class by passing them to the constructor, and then set up our dogsList$ observable. We’ll use RxJS operators tap (previously known as the do operator) and catchError to call handler functions. The tap operator executes side effects but does not affect the emitted data, so it’s ideal for setting other properties. The _onNext() function will set loading to false (since data has been successfully emitted). The _onError() function will set loading and error appropriately and throw an error. As mentioned before, we don’t need to subscribe or unsubscribe from the dogsList$ observable because the async pipe (which we’ll add in the template) will handle that for us.

On initialization of our component, we’ll use ngOnInit() to spy on the OnInit lifecycle hook to set the document <title>.

That’s it for our Dogs component class!

Dogs Component Template

Let’s move on to the template at dogs.component.html:

<!-- src/app/dogs/dogs/dogs.component.html -->
<h1 class="text-center">{{ pageTitle }}</h1>

<ng-template #noDogs>
  <app-loading *ngIf="loading"></app-loading>
  <app-error *ngIf="error"></app-error>
</ng-template>

<div *ngIf="dogsList$ | async as dogsList; else noDogs">
  <p class="lead">
    These were the top <a href="http://www.akc.org/content/news/articles/the-labrador-retriever-wins-top-breed-for-the-26th-year-in-a-row/">10 most popular dog breeds in the United States in 2016</a>, ranked by the American Kennel Club (AKC).
  </p>
  <div class="row mb-3">
    <div *ngFor="let dog of dogsList" class="col-xs-12 col-sm-6 col-md-4">
      <div class="card my-2">
        <img class="card-img-top" [src]="dog.image" [alt]="dog.breed">
        <div class="card-body">
          <h5 class="card-title">#{{ dog.rank }}: {{ dog.breed }}</h5>
          <p class="text-right mb-0">
            <a class="btn btn-primary" [routerLink]="['/dog', dog.rank]">Learn more</a>
          </p>
        </div>
      </div>
    </div>
  </div>
</div>

<app-comments></app-comments>

There are a couple things in this template that we’ll take a closer look at:

...
<ng-template #noDogs>
  <app-loading *ngIf="loading"></app-loading>
  <app-error *ngIf="error"></app-error>
</ng-template>

<div *ngIf="dogsList$ | async as dogsList; else noDogs">
  ...
    <div *ngFor="let dog of dogsList" ...>
      ...

This code does some very useful things declaratively. Let’s explore.

First we have an <ng-template> element with a template reference variable (#noDogs). The <ng-template> element is never rendered directly. It’s intended to be used with structural directives (such as NgIf). In this case, we’ve created an embedded view with <ng-template #noDogs> which contains both the loading and error components. Each of these components will render based on a condition. The noDogs embedded view itself will not render unless instructed to.

So how (and when) do we tell this view to render?

The next <div *ngIf="... is actually an NgIfElse using the asterisk prefix as syntactic sugar. We’re also using the async pipe with our dogsList$ observable and setting a variable so we can reference the stream’s emitted values in our template (as dogsList). If something goes wrong with the dogsList$ observable, we have an else noDogs statement that tells the template to render the <ng-template #noDogs> view. This would be true before the data has been successfully fetched from the API, or if an error was thrown by the observable.

If dogsList$ | async has successfully emitted a value, the div will render and we can iterate over our dogsList value (which is expected to be an array of Dogs, as specified in our component class) using the NgForOf (*ngFor) structural directive to display each dog’s information.

As you can see in the remaining HTML, each dog will be displayed with a picture, rank, breed, and a link to their individual detail page, which we’ll create next.

View the Dogs component in the browser by navigating to your app’s homepage at http://localhost:4200. The Angular app should make a request to the API to fetch the list of dogs and display them!

Note: We’ve also included the <app-comments> component. Since we’ve generated this component but haven’t implemented its functionality yet, it should show up in the UI as text that says “Comments works!”

To test error handling, you can stop the API server (Ctrl+c in the server’s command prompt or terminal). Then try reloading the page. The error component should display since the API cannot be reached, and we should see the appropriate errors in the browser console:

Angular app with Node.js API showing data error

Continue reading %Authenticating Firebase and Angular with Auth0: Part 2%


Source: Sitepoint

A Designer’s Guide to KPIs and Vanity Metrics

Recently we’ve been discussing how analytics can be used to drive UX design. By learning about our users’ demographics and gaining valuable insights into our users’ behavior, we can use data to inform our design decisions.

You can check out all the articles in this UX Analytics series here.

Analytics helps us to guide our users towards specific actions that meet our business objectives — such as signing up to our websites or subscribing to our services. As you probably know, we call these conversions.

In this article, I’m going to talk about the KPIs (key performance indicators) that designers should track to gain insights for improving UX.

Also, if you’ve dipped into analytics before and have been amazed by the amount of visitors you’re getting but dismayed at how many are converting, then you might be interested to know that, regarding to UX, there are a number vanity metrics that should be taken with a pinch of salt. In this article, I’ll explain what those metrics are, and why you should be skeptical about them.

Let’s dive in.

Firstly, What Are KPIs?

Wikipedia explains KPIs like this:

KPIs evaluate the success of a particular activity (such as projects, programs, products and other initiatives) in which it engages.

A KPI is a metric you can measure to determine the improvement or degradation of something (which, in our case, is user experience).

KPIs can tell you whether the website you’ve designed is achieving its business objectives or not. Some KPIs are outright useless for making these determinations, and others are dangerous if you analyze them in the wrong way.

Which brings me to vanity metrics.

What are vanity metrics?

Vanity metrics are metrics that seem useful in theory, but don’t actually describe our users or UX in any way. If a metric isn’t offering us any insights about our users, and is a metric that we can’t directly influence through design, then it’s not worth our time to track that metric and try to improve it.

Consider “Number of Visitors”, for example. As designers, we can’t influence this metric. Also, the number of visitors is useless if none of them are converting, hence there are other metrics that can be a better indicator.

So, what KPIs should I track?

Before deciding what KPIs to track, you should first determine what your business goals are. This is the number one mistake that businesses make when using analytics to inform design decisions. Is it more signups? More subscribers? Are you looking to guide users towards a contact form or checkout?

Once your goals are mapped out, you can then determine which KPIs will help you to monitor those goals. If your website is for a local service, I’d say that the ultimate goal is a call or enquiry. If your website is an ecommerce shop, the primary goal would number of sales. If you run a SaaS company, the goal which matters to you should be number of active subscriptions.

Let’s take a look at the main KPIs to keep an eye on.

1. Session Duration/Average Time on Page

Session Duration/Session Time/Time on Site/Avg. Time on Page (different analytics tools will use different terms) can be a relative measure of interest in your website. Consider this: a user lands on your website, spends only 5 seconds on it, then bounces off. You could assume that they were much less interested than the user who spent a few minutes on the website.

Page views, unique page views, and average time on page

However, you should also consider that the user might have been looking for something very specific, and your web page delivered it instantly and flawlessly, causing the visitor to leave perfectly satisfied. This is common with web pages that are informational in nature: a user has a search intent, they find it on your website, and have no other need or desire to stick around.

At this stage we don’t really know much about the user intent, but we could use other KPIs and metrics to reveal the other half of the story:

  • Where did the user come from? Google? Another website?
  • What device are they using? Maybe there’s a mobile-only issue?
  • More importantly, did the visitor actually convert?

One metric doesn’t hold all the answers. Keep asking questions.

Session Duration as a vanity metric

As you can see, Session Duration can be dangerous if you make assumptions and don’t cross-reference it with any other metrics. Visitors that spend a lot of time on a website might be desperately trying to figure out how to do something, and visitors that spent only a few seconds might have received exactly the answer they were looking for. Context matters, so do a little investigating before you start bragging about your Avg. Time on Site metrics.

You also need to be aware of a particular “flaw” with the tracking of time with certain analytics tools, especially Google Analytics. Google Analytics determines how long a user spends on a specific web page by the moment they navigate to a different page. Therefore, if a visitor only visits one web page before bouncing off, no time will be recorded (even if there was time).

Continue reading %A Designer’s Guide to KPIs and Vanity Metrics%


Source: Sitepoint

Compiling and Smart Contracts: ABI Explained

Most smart contracts are developed in a high-level programming language. The most popular currently is Solidity, with Vyper hoping to take the throne in the near future.

However, the mechanism driving Ethereum can’t understand the high-level languages, but instead talks in a much lower-level language.

The Ethereum Virtual Machine (EVM)

Ethereum smart contracts are sets of programming instructions being run on all the nodes running a full Ethereum client. The part of Ethereum that runs the smart contract instructions is called the EVM. It’s a virtual machine not unlike Java’s JVM. The EVM reads a low-level representation of smart contracts called the Ethereum bytecode.

The Ethereum bytecode is an assembly language made up of multiple opcodes. Each opcode performs a certain action on the Ethereum blockchain.

The question is: how do we go from this:

pragma solidity 0.4.24;

contract Greeter {

    function greet() public constant returns (string) {
        return "Hello";
    }

}

to this:

PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xCFAE3217 EQ PUSH2 0x46 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5B PUSH2 0xD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x9B JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x80 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xC8 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x48656C6C6F000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 SLT 0xec 0xe 0xf5 0xf8 SLT 0xc7 0x2d STATICCALL ADDRESS SHR 0xdb COINBASE 0xb1 BALANCE 0xe8 0xf8 DUP14 0xda 0xad DUP13 LOG1 0x4c 0xb4 0x26 0xc2 DELEGATECALL PUSH7 0x8994D3E002900

Solidity Compiler

For now, we’ll be focusing on the Solidity compiler, but the same principles apply for Vyper or any other high-level language for the EVM.

First things first: install Node.js.

After you’ve done this, go to your terminal and run this:

npm install -g solc

This will install solc — the Solidity compiler. Now make an empty directory. In that directory create a file called SimpleToken.sol and put the following code:

pragma solidity ^0.4.24;

contract SimpleToken {

    mapping(address => uint) private _balances;

    constructor() public {
        _balances[msg.sender] = 1000000;
    }

    function getBalance(address account) public constant returns (uint) {
        return _balances[account];
    }

    function transfer(address to, uint amount) public {
        require(_balances[msg.sender] >= amount);

        _balances[msg.sender] -= amount;
        _balances[to] += amount;
    }
}

This is the simplest token smart contract, but it has several important features that will be useful for this tutorial. They are:

  • public functions
  • private functions
  • properties

After you’ve done this, run the newly installed solc on your file. You do this by running the following:

solcjs SimpleToken.sol

You should get an output similar to this:

Invalid option selected, must specify either --bin or --abi

And your compilation should fail.

What just happened? What is bin and what is abi?

bin is simply a compact binary representation of the compiled bytecode. The opcodes aren’t referenced by PUSH, PULL or DELEGATECALL, but their binary representations, which look like random numbers when read by a text editor.

Continue reading %Compiling and Smart Contracts: ABI Explained%


Source: Sitepoint