emGee Software Solutions Custom Database Applications

Share this

Web Design

How listening to our users helped us build a better Search Console

Google Webmaster Central Blog - Tue, 02/06/2018 - 05:13
The new Search Console beta is up and running. We’ve been flexing our listening muscles and finding new ways to incorporate your feedback into the design. In this new release we've initially focused on building features supporting the users’ main goals and we'll be expanding functionality in the months to come. While some changes have been long expected, like refreshing the UI with Material Design, many changes are a result of continuous work with you, the Search Console users.
We’ve used 3 main communication channels to hear what our users are saying:
  • Help forum Top Contributors - Top Contributors in our help forums have been very helpful in bringing up topics seen in the forums. They communicate regularly with Google’s Search teams, and help the large community of Search Console users.
  • Open feedback - We analyzed open feedback comments about classic Search Console and identified the top requests coming in. Open feedback can be sent via the ‘Submit feedback’ button in Search Console. This open feedback helped us get more context around one of the top requests from the last years: more than 90 days of data in the Search Analytics (Performance) report. We learned of the need to compare to a similar period in the previous year, which confirmed that our decision to include 16 months of data might be on the right track.
  • Search Console panel - Last year we created a new communication channel by enlisting a group of four hundred randomly selected Search Console users, representing websites of all sizes. The panel members took part in almost every design iteration we had throughout the year, from explorations of new concepts through surveys, interviews and usability tests. The Search Console panel members have been providing valuable feedback which helped us test our assumptions and improve designs.
In one of these rounds we tested the new suggested design for the Performance report. Specifically we wanted to see whether it was clear how to use the ‘compare’ and ‘filter’ functionalities. To create an experience that felt as real as possible, we used a high fidelity prototype connected to real data. The prototype allowed study participants to freely interact with the user interface before even one row of production code had been written.
In this study we learned that the ‘compare’ functionality was often overlooked. We consequently changed the design with ‘filter’ and ‘compare’ appearing in a unified dialogue box, triggered when the ‘Add new’ chip is clicked. We continue to test this design and others to optimize its usability and usefulness.
We incorporated user feedback not only in practical design details, but also in architectural decisions. For example, user feedback led us to make major changes in the product’s core information architecture influencing the navigation and product structure of the new Search Console. The error and coverage reports were originally separated which could lead to multiple views of the same error. As a result of user feedback we united the error and coverage reporting offering one holistic view.
As the launch date grew closer, we performed several larger scale experiments. We A/B tested some of the new Search Console reports against the existing reports with 30,000 users. We tracked issue fix rates to verify new Search Console drives better results and sent out follow-up surveys to learn about their experience. This most recent feedback confirmed that export functionality was not a nice-to-have, but rather a requirement for many users and helped us tune detailed help pages in the initial release.
We are happy to announce that the new Search Console is now available to all sites. Whether it is through Search Console’s feedback button or through the user panel, we truly value a collaborative design process, where all of our users can help us build the best product.
Try out the new search console.
We're not finished yet! Which feature would you love to see in the next iteration of Search Console? Let us know below.
Posted by the Search Console UX team
Categories: Web Design

Persisted WordPress Admin Notices: Part 2

Tuts+ Code - Web Development - Tue, 02/06/2018 - 05:00

In part one of this series, we learned how to implement a basic admin notice that appears at the top of every WordPress admin page. In this tutorial, we'll start to build out a plugin to contain all our custom admin notice code.

We'll begin by implementing standard admin notices and use them as a base for more flexible and advanced examples.

Setting Up Our Plugin

First, though, let's set up a new plugin from scratch that we'll be using for all our admin notices so we're ready to start entering code.

I'll assume here that you already have a local WP development site set up. If not then refer back to the links in part one of this tutorial series.

Create a new plugin folder called admin_notices inside /wp-content/plugins/, and then create an admin_notices.php file which will be the main plugin file.

Open up admin_notices.php in your favorite editor and add the basic plugin structure:

<?php /* Plugin Name: Admin Notices Description: Display your own custom admin notices. Version: 0.1 Author: David Gwyer Author URI: http://www.wpgoplugins.com */ class Gwyer_Admin_Notices { /** * Register hooks. */ public function init() { // Add code here... } } $gwyer_admin_notices = new Gwyer_Admin_Notices(); $gwyer_admin_notices->init();

We added a basic plugin header so WordPress recognises our plugin. This is followed by a class that will contain methods to display our admin notices.

I named the class Gwyer_Admin_Notices to try and make it as unique as possible. This way, it's much less likely to conflict with an existing class name.

Let's start by displaying a basic admin notice, and then add to it to make it more useful. To create an admin notice, add the admin_notices hook to the init() function:

add_action( 'admin_notices', array( $this, 'test_notice' ) );

The hook includes a test_notice callback function which will be used to output the admin notice markup.

Add the following class method to Gwyer_Admin_Notices to display the actual admin notice. For the messages, we'll be using classic movie quotes from the last 100 years of movies.

/** * Output a test admin notice. */ public function test_notice() { ?> <div class="notice notice-error"><p>Yoo hoo, big summer blow out.</p></div> <?php }

Activate the plugin to show the test notice.

Let's also add examples of the other types of admin notice we can display including the dismissible type by adding the is-dismissible CSS class. Add these to the test_notice() method underneath the existing admin notice div:

<div class="notice notice-warning"><p>Toto, I've a feeling we're not in Kansas anymore.</p></div> <div class="notice notice-success"><p>You had me at "hello".</p></div> <div class="notice notice-info"><p>Of all the gin joints in all the towns in all the world, she walks into mine.</p></div> <div class="notice notice-success is-dismissible"><p>Nobody puts Baby in a corner.</p></div>

This is the full array of admin notice types we can display via the WordPress core CSS classes. Remember, though, that the dismissible admin notice will reappear on each page load!

'Dismissible' admin notice in this context means only for the current page. Having persistent admin notices isn't very flexible, so later on we'll be specifically looking at different ways you can dismiss your admin notices effectively.

Admin Notice Hooks

So far, we've only used the admin_notice hook to implement an admin notice. There are in fact four separate admin notice hooks that you can use to display notifications, but admin_notice is the one most commonly used.

The four hooks available are:

*No official documentation currently available for these hooks.

So where would you typically use all_admin_notices, user_admin_notices, and network_admin_notices? And how do they differ from admin_notices?

I said previously that the admin_notices hook displays notifications on all admin pages, but this isn't strictly true. If you take a look at admin-header.php in WordPress core, you'll see that admin_notices, network_admin_notices, and user_admin_notices are mutually exclusive. That is, only one of these hooks fires on a WordPress admin page.

A series of conditional expressions evaluates the current admin page and fires just one of them depending on the type of admin page you're currently on.

Firstly, is_network_admin() checks to see if you're on a network admin screen (e.g. any admin page based on a /wp-admin/network/ URL). If so, the network_admin_notices hook fires.

Otherwise, is_user_admin() checks to see if you're on a user admin screen (e.g. any admin page based on a /wp-admin/user/ URL). If so, the user_admin_notices hook fires. 

And, as you might have guessed, if both is_network_admin() and is_user_admin() return false then the admin_notices hook fires.

That just leaves the all_admin_notices hook. This hook isn't part of the conditional expression discussed above, so this hook is guaranteed to display on all admin pages no matter what, including multisite network admin pages.

To clarify, for any WordPress admin page, only the all_admin_notices hook is guaranteed to always fire. Out of the other three hooks, only one will fire depending on the admin page you're currently on.

I'd encourage you to take a look at admin-header.php (towards the end of the file) to see for yourself how WordPress evaluates when to use each admin notices hook.

We'll only be using admin_notices throughout this tutorial series, but you may find you have a need for some of the other hooks in your own project, so it's well worth checking them out.

Displaying Admin Notices on Specific Pages

Let's turn our attention now to displaying admin notices on specific pages. First, comment out the call to add_action so our test notices aren't displayed anymore.

Inside init(), add a new add_action() call that we'll use to display an admin notice on one specific admin page.

add_action( 'admin_notices', array( $this, 'specific_admin_page' ) );

Then define the specific_admin_page() method as follows:

/** * Output an admin notice on a specific admin screen. */ public function specific_admin_page() { $admin_page = get_current_screen(); ?> <div class="notice notice-info"><p>Information: We are currently on the <strong><?php echo $admin_page->base; ?></strong> admin page.</p></div> <?php }

Save your changes and view any page in the WordPress admin. I'll try the main dashboard page.

As you can see, for any admin page you visit, the (base) name of the page is being displayed in the admin notice.

The get_current_screen() function returns a WP_Screen object with details about the current admin screen. The particular object property we're interested in is WP_Screen->base, which evaluates to the base type of the current screen. Try loading different WordPress admin pages to see what values are returned for WP_Screen->base.

We can use the base value to conditionally load our admin notice only on the dashboard page. The value we need to check for is dashboard. Let's also show an alternative admin notice if we aren't on the admin dashboard page. Replace your definition of specific_admin_page() with:

/** * Output an admin notice on a specific admin screen. */ public function specific_admin_page() { $admin_page = get_current_screen(); if( $admin_page->base == "dashboard" ) : ?> <div class="notice notice-success"><p>We made it! Welcome to the dashboard.</p></div> <?php else : ?> <div class="notice notice-error"><p>Where did you go? This isn't the dashboard!</p></div> <?php endif; }

Everything's fine when we're on the dashboard page, but try navigating to any other admin page and see what happens.

Using this simple approach gives us quite a bit of flexibility when displaying admin notices on specific admin pages. We can easily extend this to whitelist any number of admin pages we want to show admin notices on.

Once again, replace the specific_admin_pages() function, this time with the following code:

/** * Output an admin notice on a specific admin screen. */ public function specific_admin_page() { $whitelist_admin_pages = array( 'dashboard', 'upload', 'edit-comments' ); $admin_page = get_current_screen(); if( in_array( $admin_page->base, $whitelist_admin_pages ) ) : ?> <div class="notice notice-success"><p>We made it! This is the '<?php echo $admin_page->base; ?>' admin page.</p></div> <?php else : ?> <div class="notice notice-error"><p>Not on your nelly! This page isn't on my list.</p></div> <?php endif; }

Instead of checking for a single admin page, we now check to see if the base name for the current admin page is in the $whitelist_admin_pages array. When we navigate to the dashboard, media library, or comments admin pages, we see our success admin notice.

And when we visit any other admin page (not included in our whitelist array), we see an alternate admin notice.

What about displaying an admin notice on a plugin options page? How would we go about that? Before we get into this, we first need to set up a dummy options page for our plugin.

Create a new file called plugin-options.php inside the admin-notices plugin folder we added earlier, and add the following code:

<?php class Gwyer_Plugin_Options { /** * Register hooks. */ public function init() { add_action( 'admin_init', array( $this, 'register_plugin_settings' ) ); add_action('admin_menu', array( $this, 'create_admin_menu_page' ) ); } public function create_admin_menu_page() { // Create new top-level menu add_options_page('Admin Notices', 'Admin Notices', 'manage_options', __FILE__, array( $this, 'render_options_page' ) ); } public function register_plugin_settings() { register_setting( 'admin-notices-plugin-settings', 'text-option' ); } public function render_options_page() { ?> <div class="wrap"> <h1>Admin Notices Plugin</h1> <form method="post" action="options.php"> <?php settings_fields( 'admin-notices-plugin-settings' ); ?> <?php do_settings_sections( 'admin-notices-plugin-settings' ); ?> <table class="form-table"> <tr valign="top"> <th scope="row">Enter some text</th> <td><input type="text" name="text-option" value="<?php echo esc_attr( get_option( 'text-option' ) ); ?>" /></td> </tr> </table> <?php submit_button(); ?> </form> </div> <?php } } $gwyer_plugin_options = new Gwyer_Plugin_Options(); $gwyer_plugin_options->init();

At the top of admin-notices.php (directly above the class declaration), include the plugin options class into the main plugin file with:

require_once(dirname(__FILE__) . '/plugin-options.php' );

I'm not going into too much detail on how the code in plugin-options.php works as that could be a whole tutorial on its own! If you want a refresher then I'd recommend taking a look at the WordPress Codex page on adding plugin options pages.

Basically, all we're doing is adding a new Admin Notices subpage to the Settings menu. The plugin options page itself contains a single text field which you can enter a string into. When the Save Changes button is clicked, the contents of the text field are saved to the WordPress database.

This is only a bare-bones example of a plugin settings page just for demonstration. It doesn't include the necessary sanitization or translation functions recommended for a production plugin intended for general release.

Go to Settings > Admin Notices to view the plugin options page.

As expected, the admin notice we added previously displays on our plugin options page. The error message is displayed because our plugin options page isn't in the $whitelist_admin_pages array of allowed admin pages. Let's fix that now.

In order to add our options page to the array, we need to know the base name. Inside specific_admin_page(), change the error admin notice div to the following:

<div class="notice notice-error"><p>Not on your nelly! This '<?php echo $admin_page->base; ?>' page isn't on my list.</p></div>

We still get the same error admin notice as before, but this time it includes the base name we need, which turns out to be settings_page_admin-notices/plugin-options. That's not a name we could have easily guessed, so it was worth taking the time to output it!

Add the base name to the $whitelist_admin_pages array, which should now look like this:

$whitelist_admin_pages = array( 'settings_page_admin-notices/plugin-options', 'dashboard', 'upload', 'edit-comments' );

Refresh the plugin options page to see the updated admin notice.

Now that we know the plugin options page base name, we can easily create an admin notice that only displays on that admin page. Remove settings_page_admin-notices/plugin-options from the $whitelist_admin_pages array and comment out the second add_action function call in init(). Then add a third action we'll use for our plugin options page only admin notice. Your init() function should now look like this:

/** * Register hooks. */ public function init() { //add_action( 'admin_notices', array( $this, 'test_notice' ) ); //add_action( 'admin_notices', array( $this, 'specific_admin_page' ) ); add_action( 'admin_notices', array( $this, 'plugin_admin_notice' ) ); }

Let's flesh out the plugin_admin_notice() callback function now. Add this new method to the Gwyer_Admin_Notices class:

/** * Output an admin notice on the plugin options page. */ public function plugin_admin_notice() { $whitelist_admin_pages = array( 'settings_page_admin-notices/plugin-options' ); $admin_page = get_current_screen(); if( in_array( $admin_page->base, $whitelist_admin_pages ) ) : ?> <div class="notice notice-info"><p>Welcome to the Admin Notices plugin page!</p></div> <?php endif; }

This is very similar to specific_admin_page() except we've removed the conditional expression. We also added a dismissible button by adding the is-dismissible CSS class, so the admin notice can now be closed too.

Try loading other admin pages to confirm that the admin notice only displays on the plugin options page.


In this tutorial, we learned more about admin notices and the various hooks available for displaying them. We also covered how to display admin notices only on specific pages of the WordPress admin. We developed a dedicated plugin to contain all the custom admin notice code.

In part three, we'll further extend the plugin by showing how to trigger admin notices when certain events occur. Remember, the open-source nature of WordPress makes it easy to learn and extend. To that end, we have much to review and study in Envato Market if you're curious.

We'll then turn our attention to finding out how we can solve the persistent admin notice issue so that they don't reappear when the page is refreshed. We'll implement several different methods in our custom plugin to allow us to do this.

Categories: Web Design

Create Your First Angular App: Storing and Accessing Data

Tuts+ Code - Web Development - Tue, 02/06/2018 - 04:00

In the first tutorial of the series, we learned how to get started in order to create an Angular app. After successfully completing that tutorial, you should now have your first functioning Angular app with the heading 'Fun Facts About Countries'. Before creating any components that can be rendered on the screen, we will create some classes and define some functions that make those components useful.

In this tutorial, our focus will be on creating a Country class which will contain different properties whose value we want to display to the user. We will then create another file named country-data.ts. This file will contain information about all the countries in our app. Our third file will be named country.service.ts. The name may sound fancy, but the file will just contain a CountryService class with all the necessary functionality to retrieve and sort the information provided by the file country-data.ts.

Creating a Country Class

Inside the src/app folder of your Angular app, create a file named country.ts. Add the following code inside it.

export class Country { name: string; capital: string; area: number; population: number; currency: string; gdp: number; }

The above TypeScript code defines the Country class with six different properties to store information about different countries. The name of the country, its capital, and its currency are stored as a string. However, its area, population, and GDP are stored as a number. We will be importing the Country class in a lot of places, so I have added the export keyword before the class definition.

Creating an Array of Countries

The next step includes creating a country-data.ts file to store the information about all the countries as an array of Country objects. We will be importing the Country class in this file and then exporting a const named COUNTRIES which stores an array of country objects. 

Here is the code for country-data.ts. Just like country.ts, you have to create this file inside the src/app folder.

import { Country } from './country'; export const COUNTRIES: Country[] = [ { name: 'Russia', capital: 'Moscow', area: 17098246, population: 144463451, currency: 'Russian Ruble', gdp: 1283162 }, { name: 'Canada', capital: 'Ottawa', area: 9984670, population: 35151728, currency: 'Canadian Dollar', gdp: 159760 }, { name: 'China', capital: 'Beijing', area: 9596961, population: 1403500365, currency: 'Renminbi (Yuan)', gdp: 11199145 }, { name: 'United States', capital: 'Washington, D.C.', area: 9525067, population: 325365189, currency: 'United States Dollar', gdp: 18569100 }, { name: 'Japan', capital: 'Tokyo', area: 377972, population: 12676200, currency: 'Yen', gdp: 4939384 } ];

The first line in this file imports the Country class from the country.ts file located in the same directory. If you remove this line from the file, TypeScript will give you the following error:

Cannot find name 'Country'.

Without the import statement, TypeScript will have no idea what an array of type Country means. So make sure that you have imported the right class and specified the location of country.ts correctly.

After importing the Country class, we go ahead and create an array of Country objects. We will be importing this array of countries for use within other files, so we add an export keyword to this array as well. Currently, there are five different Country objects in the array. Each of these five objects provides key-value pairs that list the name of a property and its value for a particular object or country.

If you try to add an additional property to the array which has not been declared inside the Country class definition, you will get the following error:

Object literal may only specify known properties, and 'president' does not exist in type 'Country'

In this case, I was trying to store the name of the president as a string inside a property named president. Since no such property was declared, we got an error. Sometimes, you might want to specify a property only for particular objects and not for others. In such cases, you can mark the property optional inside the class definition. I have discussed it in more detail in a tutorial which covers TypeScript Interfaces.

For now, just make sure that the names of all the properties match the names inside the class definition. Also make sure that the value of each property has the same type as declared in the class definition.

Creating a CountryService Class

After creating our Country class and COUNTRIES array, we can now finally write some functions to process the country data. We will need to import both the Country class and the COUNTRIES array inside our service file. The file will need to import the COUNTRIES array in order to have access to the data. Similarly, the file will have to import the Country class in order to make sense of the data inside the COUNTRIES array.

We will also be importing other dependencies like Injectable from Angular core to make our CountryService class available for the Injector to inject in other components.

Once your app grows in size, different modules will need to communicate with each other. Let's say that ModuleA requires ModuleB in order to work properly. In such cases, we would call ModuleB a dependency of ModuleA. 

Simply importing the module we need into another file works most of the time. However, sometimes we need to decide if we should create a single instance of classes from ModuleB that will be used by the whole app or if we should create a new instance every time the module is used. In our case, we will be injecting a single instance of our CountryService class throughout the app.

Here is the code for country.service.ts:

import { Injectable } from '@angular/core'; import { Country } from './country'; import { COUNTRIES } from './country-data'; @Injectable() export class CountryService { constructor() { } getCountries(): Country[] { return COUNTRIES; } getPopulatedCountries(): Country[] { return COUNTRIES.sort((a, b) => b.population - a.population).slice(0, 3); } getLargestCountries(): Country[] { return COUNTRIES.sort((a, b) => b.area - a.area).slice(0, 3); } getGDPCountries(): Country[] { return COUNTRIES.sort((a, b) => b.gdp - a.gdp).slice(0, 3); } getCountry(name: string): Country { return COUNTRIES.find(country => country.name === name); } }

An @injectable decorator is used to identify a service class that might require injected dependencies. However, adding the @injectable to service classes is a required coding style, so we do it anyway.

After that, we write different methods for the class which take the COUNTRIES array and either return it directly or sort it using certain criteria and then return a part of the array. 

The getCountries() method is expected to return all the Country objects, and so it returns the whole COUNTRIES array without making any modifications to it.

The getPopulatedCountries() takes the COUNTRIES array and sorts it in descending order based on the population of different countries. We then use the Array.slice() method in order to return the first three countries (with indices 0, 1, and 2) from the array. The getLargestCountries() and getGDPCountries() methods work in a similar fashion.

The getCountry() method takes a name as its argument and returns the country object whose name property has the same value as the supplied name argument.

Including CountryService in app.module.ts

A service that you create is just a class in Angular until you have registered it with an Angular dependency injector. An Angular injector will be the one responsible for creating service instance(s) and injecting them into different classes which need that service. We need to register a service with a provider before the injector can create that service.

There are two common ways to register any service: using a @Component provider or using the @NgModule provider. Using the @Component provider makes sense when you want to restrict the access of a service to a particular component and all its nested components. Using the @NgModule provider makes sense when you want multiple components to have access to the service.

In our case, we will be using CountryService with multiple components of our app. This means that we should register it with the @NgModule provider once, instead of registering it separately with the @Component provider of each component. 

Currently, your app.module.ts file should look like this:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

Add an import statement to the app.module.ts file and add the service to the @NgModule providers array. After making these changes, your app.module.ts file should look like this:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { CountryService } from './country.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [CountryService], bootstrap: [AppComponent] }) export class AppModule { }

The CountryService class will now be available to all the components that we create for our app.

Final Thoughts

Successfully creating three files named country.ts, country-data.ts, and country.service.ts concludes the second tutorial of this series.

The country.ts file is used to create a Country class with different properties like name, currency, population, area, etc. The country-data.ts file is used to store an array of country objects which have information about different countries. The country.service.ts file contains a service class with different methods to access the country data from the COUNTRIES array. Writing all these methods separately inside a service class allows us to access them inside different app components from a central location.

In the last section, we registered our service with the @NgModule provider to make it available for use inside different components.

The next tutorial will show you how to create three different components in your app to display country details and a list of countries.

Categories: Web Design

Exploring New Worlds: A Smashing Creativity Challenge

Smashing Magazine - Tue, 02/06/2018 - 03:30
Time flies! Did you know that it has been more than nine years already since we first embarked on our wallpapers adventure? Nine years is a long time, and sometimes we all should break out of our comfort zones and try something new, right? We'd love to invite you to a little creativity challenge: Get out your pens, paint brushes, camera, or fire up your favorite illustration tool, and design a desktop wallpaper for March 2018.
Categories: Web Design

Launching SEO Audit category in Lighthouse Chrome extension

Google Webmaster Central Blog - Mon, 02/05/2018 - 08:52

We're happy to announce that we are introducing another audit category to the Lighthouse Chrome Extension: SEO Audits.

Lighthouse is an open-source, automated auditing tool for improving the quality of web pages. It provides a well-lit path for improving the quality of sites by allowing developers to run audits for performance, accessibility, progressive web apps compatibility and more. Basically, it "keeps you from crashing into the rocks", hence the name Lighthouse.

The SEO audit category within Lighthouse enables developers and webmasters to run a basic SEO health-check for any web page that identifies potential areas for improvement. Lighthouse runs locally in your Chrome browser, enabling you to run the SEO audits on pages in a staging environment as well as on live pages, public pages and pages that require authentication.

Bringing SEO best practices to you

The current list of SEO audits is not an exhaustive list, nor does it make any SEO guarantees for Google websearch or other search engines. The current list of audits was designed to validate and reflect the SEO basics that every site should get right, and provides detailed guidance to developers and SEO practitioners of all skill levels. In the future, we hope to add more and more in-depth audits and guidance — let us know if you have suggestions for specific audits you'd like to see!

How to use it

Currently there are two ways to run these audits.

Using the Lighthouse Chrome Extension:
  1. Install the Lighthouse Chrome Extension
  2. Click on the Lighthouse icon in the extension bar 
  3. Select the Options menu, tick “SEO” and click OK, then Generate report

Running SEO Audits in Lighthouse extension

Using Chrome Developer tools on Chrome Canary:
  1. Open Chrome Developer Tools 
  2. Go to Audits 
  3. Click Perform an audit 
  4. Tick the “SEO” checkbox and click Run Audit

Running SEO Audits in Chrome Canary
The current Lighthouse Chrome extension contains an initial set of SEO audits which we’re planning to extend and enhance in the future. Once we're confident of its functionality, we’ll make the audits available by default in the stable release of Chrome Developer Tools.

We hope you find this functionality useful for your current and future projects. If these basic SEO tips are totally new to you and you find yourself interested in this area, make sure to read our complete SEO starter-guide! Leave your feedback and suggestions in the comments section below, on GitHub or on our Webmaster forum.

Happy auditing!

Posted by Valentyn, Webmaster Outreach Strategist.
Categories: Web Design

Creating Your First Angular App: Basics

Tuts+ Code - Web Development - Mon, 02/05/2018 - 05:41

Angular has become very popular over the past couple of years. You can use this open-source JavaScript framework to build web and mobile apps. If you've been thinking about learning Angular but don't know where to start, following this series might be a good idea.

The aim of this series is to cover the basics of Angular while creating a very simple app that shows information about different countries. Angular is written in TypeScript, so it makes sense that you write your own code in TypeScript as well. 

There's no need to worry if you have never used TypeScript before. To put it simply, TypeScript is just typed JavaScript with additional features. I have also written a series titled TypeScript for Beginners on Envato Tuts+, where you can learn the basics of TypeScript first.

Getting Started

If you are already familiar with TypeScript, you can just go ahead and start creating your first Angular app. 

The first step would be to install Node.js. You can head to the official website and download the appropriate version. The node package manager will be installed as part of Node.js.

The next step is to install TypeScript by running the following command. I recommend that you install a TypeScript version over 2.1.

npm install -g typescript

Finally, you have to install the Angular CLI by running the following command. Installing Angular CLI will make the process of creating your Angular app easier.

npm install -g @angular/cli

Now, you can create a new Angular app right out of the box by running the following command inside the terminal. Before running the command, make sure that you have moved to the directory where you want to create the app.

ng new country-app

Installing all the dependencies for the project takes some time, so please be patient while Angular CLI sets up your app. After the installation completes, you will see a folder named country-app in the current directory. You can run your app right now by changing the directory to country-app and then running ng serve in the console.

cd country-app ng serve --open

Adding --open will automatically open your app in the browser at http://localhost:4200/.

Country Information App Overview

The country information app that we are creating will have three components. The HomeComponent will show the top three countries under various categories like population, GDP, and area. You will be able to click the name of each country to read more about it. The additional information about the country is listed using another component, which we will be calling the CountryDetailComponent. There will be one more component in our app, which will be used to display a list of all the countries that we have stored in our app. 

Since this is your first Angular app, our main aim will be to keep things simple without adding any complicated functionality. Once you have a good grasp of the basics, creating more complex apps will not seem like a daunting task.

The image below is of the homepage or HomeComponent in our country information app. As you can see, there are three countries under each category, and they have been placed in descending order. While creating the HomeComponent, you will learn how to sort different countries before displaying them inside the template.

The following image shows the "all countries page" or AllCountriesComponent of our app. The layout of this component is very similar to the HomeComponent. The only difference is that this time we are listing all the countries along with their capitals.

If you click on the box of any country rendered inside either the HomeComponent or the AllCountriesComponent, you will be taken to the country detail page or CountryDetailComponent. The information provided about a country is not editable. 

There is a back button after the details of each country. This back button takes you back to the previous component or page. If you came to the CountryDetailComponent from the HomeComponent, you will be taken back to the HomeComponent. If you arrived at the CountryDetailComponent from the AllCountriesComponent, you will be taken back to the AllCountriesComponent.

Referring to different components that we are creating as pages is not technically correct. However, I am using terms like homepage or HomeComponent interchangeably because seeing a lot of unfamiliar terms like routing, components, and decorators can be intimidating for readers who have never created an Angular app before. Using these terms loosely for this series can help you learn quickly instead of getting confused by the jargon.

Angular Basics

Before we begin creating our app, you need to be comfortable with the basic concepts of Angular. This section will very briefly cover important topics like components and templates.

Components are the building blocks of an Angular app. They allow you to control the UI of your app. A basic component consists of two parts: a decorator and a class definition. You can specify the application logic for a component inside the class. 

The component decorator is used to specify information like a custom selector to identify the component, the path to the HTML template, and the style rules to be applied to the component. 

Here is a basic component decorator that sets all three values for CountryDetailComponent:

@Component({ selector: 'app-country-detail', templateUrl: './country-detail.component.html', styleUrls: ['./country-detail.component.css'] })

All the components that we create will have a custom selector which specifies the tag that renders the component inside the browser. These custom tags can have any name you want. For example, we will be creating a countryDetailComponent in the third tutorial of the series, and we will use our own custom tag called app-country-detail to render this component in the browser.

Any component that you create will consist of a template that controls what is rendered on the application page. For example, the countryDetailComponent has two div tags which act as a wrapper around the main content of the component. Each piece of information about a country is put inside its own p tag, and the name of the country is put inside an h2 tag. All these tags can be stored together as a template for the countryDetailComponent and then rendered as a unit. This template of the component can be saved as an HTML file or specified directly inside the decorator using the template attribute.

Different components of our app will need to retrieve the data to display on screen. We will be creating a service class that will contain functions to help us retrieve this data and sort or modify it one way or another. We will then use the functionality of different component classes to display this data to the user.

You can consider a Service to simply be any value, function, or feature that your application needs. Getting all the countries stored inside our application is a service, and so is sorting and displaying them. All the three components in our class will be using functions from our service to retrieve data.

When creating components for your app, you will have to import dependencies from different modules. For example, we will be importing Component from the @angular/core whenever we create a component of our own. You can also use the same syntax to import dependencies that were created by you. The part inside curly brackets is used to specify the dependency that you want to import, and the part after from is used to specify where Angular can find the dependency.

Here is a code snippet from the country-app that we will be creating. As you can see, we are importing Component and OnInit from the @angular/core. Similarly, we are importing a Country and CountryService from files that we created ourselves.

import { Component, OnInit } from '@angular/core'; import { Country } from '../country'; import { CountryService } from '../country.service';The Application Shell

After you ran the ng new country-app command, the Angular CLI created a bunch of files and folders for you. Seeing so many files can be intimidating as a beginner, but you don't need to work with all those files. When creating our country app, we will only be modifying the files already existing inside the src/app folder as well as creating new files in the same directory. Right now, you should have five different files in the src/app folder. These files create an application shell which will be used to put together the rest of our app.

The app.component.ts file contains the logic for our component written in TypeScript. You can open this file and update the title property of the AppComponent class to 'Fun Facts About Countries'. The app.component.ts file should now have the following code.

import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Fun Facts About Countries'; }

The app.component.html file contains the template for our AppComponent class. Open the app.component.html file and replace the boilerplate HTML code inside it with the following line:


By wrapping title inside the curly brackets, we are telling Angular to put the value of title property of the AppComponent class inside the h1 tag. 

We will be updating this file in the last tutorial of the series to render new components that we will be creating. For now, it just needs to show the title of our app. 

The changes made to this file will be automatically reflected in the browser at http://localhost:4200/. Just make sure that the console is still open and you have already typed in the ng serve command from the beginning of the tutorial. 

Different functions and features of the app will be controlled by multiple simpler components that we will create later. You can think of this application shell as a car and different components that we will create as parts of that car like the engine and the wheels. Each component will perform its specific function, and you can put them all together to create the whole car.

Final Thoughts

The aim of this tutorial was to help you install all the necessary tools that you need to create an Angular app and quickly go over some fundamental Angular concepts.

To summarize, you need to know the basics of TypeScript before you can create an Angular app. In the next step, you need to install Node.js, TypeScript, and the Angular CLI. After that, you can just run a bunch of commands from the Getting Started section of this tutorial, and your first Angular app will be up and running.

Our country app will do a lot more than just show the title. In the next tutorial, you will create a few classes and services that will be used to store and retrieve data about different countries. These classes and services will be useful in the third and fourth tutorials, where we will create different components of our app.

While we're working through this tutorial series, don't forget to check out Envato Market to see what's available for use and study for both Angular and JavaScript, in general. 

Categories: Web Design

Persisted WordPress Admin Notices: Part 1

Tuts+ Code - Web Development - Mon, 02/05/2018 - 05:00

WordPress admin notices provide a convenient way to display messages to users in the admin area, e.g. after a post has been updated or a plugin has been activated. They're also used by many themes and plugins to display notifications about anything from new features or security warnings to details about ongoing promotions or upgrade prompts.

WordPress core provides four different admin notices which can be used contextually to alert a user to a specific type of notice. This is achieved by displaying a unique accent color for each type of admin notice.

Admin notices are usually displayed at the top of every admin page to stand out from the main page content and be clearly noticeable. They are elegantly designed so as to not be too visually distracting.

WordPress also reuses admin notices in other locations throughout the admin interface, such as when a theme or plugin update is available. Core usage of admin notices isn't limited to just being displayed at the top of the admin screen.

Displaying an admin notice in a custom plugin or theme is relatively easy, requiring just a few lines of code, as we'll discover shortly. However, WordPress doesn't provide a way by default to dismiss a persisted admin notice.

Even though you can add a dismiss button to any admin notice, this doesn't prevent it from reappearing when the page is reloaded. Also, admin notices appear on every admin page, which is far from ideal.

If you want to have granular control over exactly when and where admin notices are displayed and to be able to dismiss them effectively, you'll need to add custom code to modify the default behavior.

What We'll Be Covering

We'll start at the beginning and explore the basics of implementing admin notices via a custom plugin, including displaying them only on specific pages in the WordPress admin.

Admin notices appear on every page by default, which isn't always what you want. For instance, you may only want to display a notification on a plugin options page. So our next port of call will be to conditionally display admin notices depending on the current admin screen.

Building on this, we'll introduce ways to further manage admin notices by controlling when they appear too. Rather than appearing as soon as the page loads, they will only appear if certain triggering conditions are met. This could be useful, for example, if you wanted to display an admin notice on a plugin options page, but only after settings had been saved.

As mentioned above, there's no easy way to dismiss persisted admin notices between page loads. So the remainder of the tutorial series will focus mainly on various methods you can employ to dismiss admin notices so they won't reappear unexpectedly.

Finally, for a bit of fun, we'll see how you can create your own custom admin notice types and add additional decoration such as icons to your admin notices.

By the end of this tutorial series, you'll be able to display any type of admin notice anywhere within the WordPress admin. Plus, you'll be able to decide whether to show them on page load or via a custom action, and you'll also be able to dismiss them in a variety of different ways, depending on your needs.

Want to Follow Along?

You'll get most out of this tutorial series if you follow along as we build out each admin notice example. The code is presented in a step-by-step approach to allow you to build a working plugin on your own as we progress through the tutorial. However, if you don't wish to type in all the code yourself, the finished plugin will be available for download in part four.

It's assumed that you have at least a rudimentary working knowledge of WordPress plugin development, including how hooks work. If not, then I'd recommend reading up on these topics via the official WordPress documentation before continuing:

In order to test the plugin code for each example, you'll need a working WordPress site. The easiest way to do this is to install WordPress locally so you have easy access to edit files. 

There are many choices for developing locally with WordPress, including:

If you're new to WordPress development then Local or DesktopServer are probably easiest to set up. Local is free to use (they have a premium version in the works), and DesktopServer has a limited (free) version plus a premium version available.

Also, some previous experience of PHP and JavaScript is recommended, as is some experience of implementing Ajax requests. However, everything will be explained along the way, so in-depth knowledge isn't required.

A Closer Look at Admin Notices

Let's take a look at the most basic implementation of an admin notice and the code required to render a success type notice.

function display_admin_notice() { ?> <div class="notice notice-success"><p>The secret to success is to know something nobody else knows ~ Aristotle Onassis</p></div> <?php } add_action( 'admin_notices', 'display_admin_notice' );

All we did here was to register the display_admin_notice() function that will be run when the admin_notices hook fires. It doesn't matter what the registered function is called—it won't affect how the admin notice is rendered.

Don't worry about entering the code above yourself right now; just focus on how the admin notice is generated as we'll be building on this in later tutorials.

You can use any markup you like to display an admin notice; however, the recommended format is as follows:

<div class="{class}"><p>{message}</p></div>

Replace {class} with a list of CSS class names. You should include the class notice plus any one of the following classes to determine the type of admin notice:

  • notice-error (red)
  • notice-warning (yellow/orange)
  • notice-success (green)
  • notice-info (blue)

The {message} block can be any text or valid HTML which will be displayed inside the admin notice.

The example above shows admin notices on all admin pages, which isn't always ideal, so in part two we'll look at how you can control exactly what pages they appear on.

There is another built-in CSS class you can add to div.notice that adds a dismiss button to the admin notice. Let's see what happens when the same success admin notice has the is-dismissible class added to it.

function display_admin_notice() { ?> <div class="notice notice-success is-dismissible"><p>The secret to success is to know something nobody else knows ~ Aristotle Onassis</p></div> <?php } add_action( 'admin_notices', 'display_admin_notice' );

We now have an easy way to dismiss an admin notice. However, before you get too excited, there's a problem with using this method. If you refresh the page, the admin notice reappears! So, even though you can set an admin notice to be dismissible, it's persistent, and the dismissed status is forgotten between page loads.

We'll be covering persistent admin notices in detail later on and exploring various ways you can dismiss them without them reappearing.

But Admin Notices Are Bad! Aren't They?

If you're at all familiar with admin notices in WordPress and/or keep up with WordPress news in general then you may be aware of a certain amount of negativity regarding using admin notices in custom plugins and themes.

This stems from some plugins overusing admin notices in an attempt to get their 'important' messages across. If you have a lot of plugins installed and just a few of them abuse the admin notice system then you can quickly end up with admin notice 'soup', where a whole tangle of notices are displayed at the top of every admin page.

Overloading admin screens with unnecessary notices can cause chaos (and headaches) and is understandably annoying for users as it makes managing a site more difficult.

Ideally, only important admin notices, such as critical security updates, should be displayed on every page load. If you're displaying global admin notices to tell users a plugin has just been updated, and prompt to click a link for more information, then you should really ask yourself whether this needs to be on every admin page.

Also, a typical favorite is to display a non-critical admin notice that can't easily be permanently dismissed. I guarantee you there is no easier way to alienate your plugin users than by doing this!

However, there are use cases for persistent notices that aren't dismissible, such as database updates. Plugins that use custom tables may need to run database update routines once in a while to keep the plugin running correctly. So, in this case, it's reasonable to add a non-dismissible admin notice.

A good rule of thumb is to just employ common sense. Would the admin notice you're about to add to your plugin annoy you as a user? If so, you might want to rethink adding the notice, or consider if it would be better displayed in an alternative location.


In this tutorial, we've covered what admin notices are and the various built-in types provided by WordPress, including a dismissible admin notice. As we've seen, there are some drawbacks to the default implementation of admin notices, such as not being dismissible and the fact they are rendered on every admin page.

WordPress has an incredibly active economy. There are themes, plugins, libraries, and many other products that help you build out your site and project. The open-source nature of the platform also makes it a great option from which you can better your programming skills. Whatever the case, you can see what we have available Envato Market.

The rest of the tutorials in this series will focus on how we can extend admin notices to be more practical when used in your own plugins and themes.

Categories: Web Design

Using Media Queries For Responsive Design In 2018

Smashing Magazine - Mon, 02/05/2018 - 04:30
Back in July 2010, I wrote an article for Smashing Magazine entitled “How To Use CSS3 Media Queries To Create A Mobile Version of Your Website.” Almost eight years on, that article still receives a lot of traffic. I thought it would be a nice idea to revisit that subject, now that we have layout methods such as Flexbox and Grid Layout. This article will take a look at the use of media queries for responsive design today, and also have a look at what is coming in the future.
Categories: Web Design

What Is The Best Advice You Have Ever Received? Our Community Speaks.

Smashing Magazine - Mon, 02/05/2018 - 01:00
The beginning of a new year seems like a perfect time to think about what we web professionals do, why we do it, how we could do it better and even how we could have more fun doing it. Like everyone, we learn lessons as we make our way through life and work. If we’re lucky, we pick up some good advice along the way, so we thought it might be useful to find out what kind of advice you all have found to be particularly valuable.
Categories: Web Design

17 Top WordPress Donation Plugins in 2018

Creating a successful non-profit website, or fundraising for a worthy cause, isn’t an easy task. Choosing an effective donation plugin is by far one of the most important decisions...

The post 17 Top WordPress Donation Plugins in 2018 appeared first on Onextrapixel.

Categories: Web Design

How To Make A Dynamic Website Become Static Through A Content CDN

Smashing Magazine - Fri, 02/02/2018 - 05:00
Smashing Magazine gave us a little surprise recently: Its website has been completely overhauled, switching away from WordPress to Netlify. One of the several reasons for the move is cost: Netlify allows for a static version of a website, which can be hosted directly on a content delivery network (CDN), reducing the number of web servers that are needed. In addition, because CDNs are located near users, accessing the website becomes faster.
Categories: Web Design

Error and Performance Monitoring for Web & Mobile Apps Using Raygun

Tuts+ Code - Web Development - Fri, 02/02/2018 - 05:00

Fixing a bug is a whole lot easier when you know how it occurred, but that may not always be the case. Once the software has been shipped, you are left at the mercy of customers, who may not always report the crash.

When the code crashes, you log the errors in the log file, and hence continues the journey of a developer to trace the occurrence of the bug by looking through the log files. Guessing the root cause of the crash from the log file may take a lot of your valuable time.

Is there an easier way to troubleshoot the cause of an error in your software application? Raygun offers a set of interesting solutions to keep an eye on errors when they arise in your web and mobile applications. 

From the official documentation, Raygun offers:

Complete visibility into problems your users are experiencing and workflow tools to solve them quickly as a team.

Raygun offers four tools to make it easier to deal with errors and crashes in your application:

  • The Raygun Crash Reporting tool helps you monitor and replicate each crash and error that occurred in your application.
  • The Real User Monitoring tool helps to capture each user session and other related information to gauge the user experience.
  • The User Tracking tool helps to categorise crashes and errors based on application users. 
  • The Raygun Deployment Tracking tool makes it easier to track each release and shows you how it affects the overall performance of the software application.

In this tutorial, you'll learn how to integrate Raygun tools with your web application to monitor and trace bugs. For this tutorial, you'll be integrating Raygun tools with an Angular web application.

Getting Started With Raygun

You can use Raygun with a number of programming languages and frameworks. For the sake of this tutorial, let's see how to get started using Raygun with an Angular web application.

To get started, you need to create an account on Raygun. Once you have created the account, you will be presented with a screen to select the preferred language or framework.

In this tutorial, you'll learn how to get started with using Raygun on an Angular web application.

Using Angular With Raygun

From the list of frameworks, select the Angular framework. You will be presented with a screen to select Angular (v2+) or Angular1.x

Since you are going to learn how to integrate Raygun with Angular 4, focus on the tab Angular (v2+)

Before integrating Raygun with Angular, you need to create an Angular application. Let's get started by creating an Angular application.

First, you'll need to install the Angular CLI globally.

npm install -g @angular/cli

Create an Angular app using the Angular CLI.

ng new AngularRaygun

You will have the Angular application created and installed with the required dependencies.

Navigate to the project directory and start the application.

cd AngularRaygun npm start

You will have the application running on http://localhost:4200/.

Install the raygun4js library using the Node Package Manager (npm).npm install raygun4js --save

Inside the src/config folder, create a file called app.raygun.setup.ts.

Copy the setup code from Step 2 of the Angular (v2+) and paste it into the app.raygun.setup.ts file.

Import the RaygunErrorHandler in the app.module.ts file inside the Angular application, and add the custom error handler. Here is how the app.module.ts file looks:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { ErrorHandler } from '@angular/core'; import { RaygunErrorHandler } from '../config/app.raygun.setup'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers: [{ provide: ErrorHandler, useClass: RaygunErrorHandler }], bootstrap: [AppComponent] }) export class AppModule { }

Now you have added a custom error handler RaygunErrorHandler, which will handle the errors.

Let's add some code to create an error. Import the Router in the app.component.ts file.

import { Router } from '@angular/router';

Modify the constructor method as shown:

constructor(private router: Router) {}

The above code will throw an error when you run the application since it hasn't been imported in the AppModule. Let's see how Raygun captures the errors. Save the above changes and restart the application. 

Point your browser to http://localhost:4200. Check the browser console and you will have the errors logged.

Raygun Dashboard

When you run the application, you will have an error logged in the browser console.

NullInjectorError: No provider for Router!

From the Raygun application, click on the Dashboard tab on the left side, and you will have detailed information about the requests logged by Raygun.

As seen in the Raygun dashboard, it shows the session count, recent request, error instance counts, etc., related to the Angular application which you configured with Raygun.

Click on the recent requests displayed on the right side of the dashboard, and you will have detailed information related to the particular request.

Raygun Crash Reporting 

Application crashes are a common scenario when dealing with software applications. Lots of these crashes occur in real-time scenarios and are hence difficult to track without a proper crash reporting system in place.

Raygun provides a tool called Crash Reporting which provides a deeper insight into application crashes. Let's have a look at how Crash Reporting works.

You have a bug in your Angular app which is crashing it. Let's see how it gets reported using Raygun Crash Reporting.

Click on the Crash Reporting tab from the menu on the left-hand side. You will have the error report listed.

In the Raygun crash reporting tab, it shows the errors that occurred in the application. In the tabs shown above, the errors have been categorized into Active, Resolved, Ignored, and Permanently ignored.

The error that you encountered while running the application has been logged under the Active tab.

On clicking the listed error, you'll be redirected to another page with detailed information related to the error. On this page, you'll have information such as the error summary, HTTP information, environment details in which the error occurred (such as the OS, browser, etc.), raw error information, and the error stack trace.

When displaying information related to a particular error, Raygun provides you with the features to change the state of the errors as per your fix. You can change the status to active, resolved, ignored, etc.

Raygun's crash reporting tool provides a feature to add comments to the errors, which is really helpful in discussing details about the bug when working in a team.

Crash Reporting: Settings

Crash reporting comes with a couple of settings which make it easier for the user to manage the errors that have occurred in the application.

It provides you with the option to enable live refresh, first seen date on an error group, and the user count on the dashboard.

You have the option to make bulk error status changes and the option to remove all the errors that occurred in the application. 

Crash Reporting: Inbound Filters

Raygun provides an option to filter requests based on the IP address, machine name, etc. If you don't want to track an error from a particular IP address, you can create an inbound filter, and the error from the application running on that IP address won't be tracked further.

Let's try to add a filter for your application running on and see if it gets tracked.

From the left side menu, under the Crash Reporting tab, click on the Inbound Filters link. Add the IP address to the filter list.

Now, if you try to run the application, on crashing it won't get tracked in the crash reporting screen since it's been filtered out.

You can also add filters based on machine names, HTTP, build versions, tag, and user agent.

Raygun User Tracking

Most of the issues encountered when the user is using the software go unreported. The probability of a frustrated user reporting an issue is quite low. Hence, you tend to lose the user feedback to improve the quality of your software.

Raygun provides an affected user tracking report. This report shows the list of users from your application who have encountered errors. It gives a full view of how that particular user encountered that particular error. You can view this report by clicking on the Users tab on the left side of the screen. 

In your Angular application, you haven't yet used the affected user details feature of Raygun. Hence in the affected user tracking report you will find the user details as anonymous along with the error details.

Click on the Anon User link from the user tracking information, and you'll see the detailed information related to that particular anonymous user. Detailed such as the active error info, user experience, sessions, devices used by the user, etc., will all be displayed in the user report.

You can add the user info details to the Raygun config file. Add the following code to the config/app.raygun.setup.ts file to send the user info details to Raygun.

rg4js('setUser', { identifier: 'roy_agasthyan_unique_id', isAnonymous: false, email: 'royagasthyan@gmail.com', firstName: 'Roy', fullName: 'Roy Agasthyan' });

Here is how the config/app.raygun.setup.ts file looks:

import * as rg4js from 'raygun4js'; import { ErrorHandler } from '@angular/core'; const VERSION_NUMBER = ''; rg4js('apiKey', 'FehB7YwfCf/F+KrFCZdJSg=='); rg4js('setVersion', VERSION_NUMBER); rg4js('enableCrashReporting', true); rg4js('enablePulse', true); rg4js('setUser', { identifier: 'roy_agasthyan_unique_id', isAnonymous: false, email: 'royagasthyan@gmail.com', firstName: 'Roy', fullName: 'Roy Agasthyan' }); export class RaygunErrorHandler implements ErrorHandler { handleError(e: any) { rg4js('send', { error: e, }); } }

Save the above changes and reload the Angular web application. Go to the Raygun application console and click on the Users tab from the left side menu. You will be able to see the new users displayed in the list of affected users.

Click on the user name to view the details associated with the particular user.

Raygun Real User Monitoring

Raygun's Real User Monitoring tool gives you an insight into the live user sessions. It lets you identify the way the user interacts with your application from the user environment and how it affects your application's performance.

Let's run your Angular application and see how it's monitored in the Real User Monitoring tool. Click on the Real User Monitoring tab in the menu on the left-hand side. You will be able to view the live user details and sessions.

By clicking on the different tabs, you can monitor the performance of the requested pages.

It gives information on the slowest and the most requested pages. Based on a number of metrics, you can monitor the pages with high loading time and fix them to improve the application's performance.

There are a number of other tabs in Real User Monitoring which give useful insight into user information based on different parameters like browsers, platforms, and user locations.

Raygun Deployment Tracking

When you release a new version of your software, it's expected to be a better version with bug fixes and patches for the issues reported in earlier versions.

Raygun provides a tool to track the deployment process and to monitor the releases. Click on the Deployments tab from the left side menu and you will be presented with information on how to configure Raygun with your deployment system. Once you have it configured, you'll be able to view the detailed report related to each release.

Setting up a deployment tracking system will enable you to get deeper insight into each of the releases. You can monitor the trend and see whether you are improving the build quality or taking it down. With each new release, you can compare the error rate and track any new errors that cropped up in the releases.

I recommend reading the official documentation to see how to integrate Raygun deployment tracking with your deployment system.

Wrapping It Up

In this tutorial, you saw how to get started using Raygun with an Angular web application. You learnt how to use the Crash Reporting tool to monitor and trace the occurrence of a crash. Using the Real User Monitoring tool, you saw how to understand the user experience details such as the page load time, average load time, etc.

The User Tracking tool lets you monitor and categorise errors and crashes based on the application users. The Deployment Tracking tool helps you track each release of your application for crashes and errors and lets you know how it's affecting the overall health of your application.

For detailed information on integrating Raygun with other languages and frameworks, I would recommend reading the official Raygun documentation.

If you have any questions and comments on today's tutorial, please post them below.

Categories: Web Design

Using Luxon for Date and Time in JavaScript

Tuts+ Code - Web Development - Fri, 02/02/2018 - 04:00

Working with date and time can be a confusing task for developers beginning with JavaScript. In this tutorial, you'll learn about a new JavaScript library called Luxon which makes it a breeze to work with date and time in JavaScript.

Throughout the course of this tutorial, you'll learn about the different features of the Luxon library and how to use it in your web application projects.

Getting Started

You'll be creating an Angular project and will see how to use the Luxon library for date and time manipulation in Angular. Let's get started by creating an Angular web app.

ng new AngularLuxon

Once you have the project created, navigate to the project directory and create a new component called luxdate.

ng g component luxdate

You will have the LuxdateComponent created and added to the application module in the app.module.ts file. Remove the default AppComponent from the application by deleting the component files from the src/app folder. Here is how the app.module.ts file looks:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { LuxdateComponent } from './luxdate/luxdate.component'; @NgModule({ declarations: [ LuxdateComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [LuxdateComponent] }) export class AppModule { }

Modify the src/index.html file to add the LuxdateComponent.

<body> <app-luxdate></app-luxdate> </body>

Save the above changes and start the server.

npm start

You will have the application running at http://localhost:4200/.

Let's import the Luxon library into your application.

npm install --save luxon

Once you have Luxon installed in the Angular application, import it in the LuxdateComponent component. Now you are ready to use the Luxon library in your project.

Local Time & UTC Time Using Luxon

Let's have a look at how to get the local time using the Luxon library. Import DateTime from the Luxon library.

import { DateTime } from 'luxon';

Inside the LuxdateComponent, define a variable called localDatetime.

public localDatetime;

Set the value of the localDatetime variable as shown:

this.localDatetime = DateTime.local();

Render the localDatetime variable in the luxdate.component.html file.

<div class="container"> <div> <div class="local"> <span> {{localDatetime}} </span> </div> </div> </div>

Save the changes and you will have the local time displayed on the web page.


The date and time displayed above is the local time with the time zone attached. You can format the date and time further to make it more intuitive.

Format the date and time to display using the below line of code.

this.localDatetime = DateTime.local().toLocaleString(DateTime.DATETIME_FULL);

Save the above line of code, and you will have the following date and time displayed.

December 31, 2017, 10:35 PM GMT+5:30

Similarly, the .utc method in the DateTime object gives the UTC time. 

Add a new variable in the LuxdateComponent to set the UTC time.

public utcDatetime;

Set the value of the utcDatetime variable using the Luxon Datetime object. 

this.utcDatetime = DateTime.utc().toLocaleString(DateTime.DATETIME_FULL);

Render the utcDatetime variable in the luxdate.component.html file as shown:

<div class="container"> <h2>Luxon Library</h2> <div class="time"> <div class="local"> <span class="label"> Local time : </span> <span> {{localDatetime}} </span> </div> <div class="utc"> <span class="label"> UTC time : </span> <span> {{utcDatetime}} </span> </div> </div> </div>

Add the following CSS style to the luxdate.component.css file. 

.container{ text-align: center; width: 100%; } .time{ display: inline-block; } .local{ border: 1px solid #8c8282; text-align: left; background-color: burlywood; padding: 10px; } .utc{ margin-top: 30px; border: 1px solid #8c8282; text-align: left; background-color: burlywood; padding: 10px; } .label{ font-family: serif; font-size: 22px; font-style: initial; }

Save the above changes, and you will be able to view the local time and the UTC time using the Luxon library.

In order to display the local time and UTC time with seconds included, you can use DATETIME_FULL_WITH_SECONDS. Here is how it will look:

ngOnInit() { this.localDatetime = DateTime.local().toLocaleString(DateTime.DATETIME_FULL_WITH_SECONDS); this.utcDatetime = DateTime.utc().toLocaleString(DateTime.DATETIME_FULL_WITH_SECONDS); }

Save the changes, and you will have the local time and UTC time displayed with seconds.

General Date and Time Information Using Luxon

The Luxon library provides an Info class which helps in getting some general information regarding date and time.

When dealing with date and time, it's quite common that you may need the list of months in a year. Using the Info class, you can get the list of months as an array. 

Import the Info class in the luxdate.component.ts file.

import { DateTime, Info } from 'luxon';

Declare a variable for the list of months and initialize it.

public months; constructor() { this.months = []; }

Set the month list from the Info class.

this.months = Info.months();

Add the following HTML to the luxdate.component.html file to display the months variable content.

<div class="month"> <span class="label"> Month : </span> <span> <select> <option *ngFor="let month of months; let i = index"> {{month}} </option> </select> </span> </div>

Save the above changes, and you will have the month list populated.

Similarly, using the weekdays method gives you a list of the weekdays.

this.weeks = Info.weekdays();

Save the changes, and you will have the weekdays listed on the screen.

Luxon also provides an option to get the list of meridiems using the meridiems method.

this.meridians = Info.meridiems();

Modify the HTML code in the luxdate.component.html to display the weeks and meridians.

<div class="month"> <span> <select> <option *ngFor="let month of months; let i = index"> {{month}} </option> </select> </span> <span> <select> <option *ngFor="let week of weeks; let i = index"> {{week}} </option> </select> </span> <span> <select> <option *ngFor="let meridian of meridians; let i = index"> {{meridian}} </option> </select> </span> </div>

Save the changes, and you will be able to view the weeks and meridians displayed.

Handling Internationalization Using Luxon 

Luxon provides a Setting class, using which you can handle Luxon's overall behavior. Let's set the default locale setting of Luxon to el.

Import the Settings class in the luxdate.component.ts file.

import { DateTime, Settings, Info } from 'luxon';

In the constructor method of LuxdateComponent, set the default locale as shown:

constructor() { Settings.defaultLocale = 'el'; }

Save the changes, and you will have the default locale set to el.

Zone Info Using Luxon

The Luxon library provides an interface to get the details related to the zone of a particular DateTime object. To use it, you need to import Zone from the Luxon library.

import { DateTime, Settings, Info, Zone } from 'luxon';

Let's try to use Zone on a Luxon DateTime object. Create a local DateTime Luxon object.

let dateObj = DateTime.local();

You can use the Zone interface on the dateObj to get the zone name. Add the following code to log the zone name.

console.log('Zone name is ', dateObj.zone.name);

Save the changes, and on running the app, you will be able to view the zone name logged in the browser console.

Zone name is Asia/Kolkata

Let's try to print the zone name of a UTC DateTime object.

let utcObj = DateTime.utc(); console.log('Zone name is ', utcObj.zone.name);

The above code will print the zone name as UTC.

Zone name is UTC

The Luxon Zone interface provides a method to compare two timezones. Let's try to compare the timezone of the DateTime objects localObj and utcObj.

if(localObj.zone.equals(utcObj.zone)){ console.log('Both zones are equal'); } else{ console.log('Both zones are different'); }

As seen in the above code, you have used the zone.equals method to compare the zones. Save the changes and try running the app, and you will have the result logged.

Both zones are differentInterval In Luxon

Interval in Luxon is a wrapper for two DateTime endpoints which can be manipulated using the Luxon methods. From the official documentation:

An Interval object represents a half-open interval of time, where each endpoint is a DateTime. Conceptually, it's a container for those two endpoints, accompanied by methods for creating, parsing, interrogating, comparing, transforming, and formatting them.

There are a couple of different ways of creating an interval using Luxon. Let's look at how to create an interval using a start and end DateTime object.

Import Interval from Luxon in LuxdateComponent. 

import { Interval } from 'luxon';

Create a start DateTime object and an end DateTime object.

let startDate = DateTime.local(); let endDate = DateTime.local().plus({minutes : 15});

As seen in the above code, you created the startDate using the current local time and endDate by incrementing the local time by 15 minutes.

Create an interval using the fromDateTimes method.  

let intv = Interval.fromDateTimes(startDate, endDate); console.log('Interval is ',intv);

Save the above changes, and on running the application, you will have the interval logged.

Now you can apply the Luxon method to manipulate or format the start and end time in the interval object. Let's say you want to check the zone name of the start time in the interval. You can do so by using the zone.name property as shown:

console.log('Start date zone is ',intv.s.zone.name);

You will have the following output logged in the browser console:

Start date zone is Asia/KolkataCreating Duration Using Luxon

Luxon provides a couple of methods to create duration. To get started with creating duration, you need to import Duration in your LuxdateComponent.

import { Duration } from 'luxon';

Once it's imported, you can use the fromMillis method to create a duration by specifying the milliseconds.

let fiveMinute = Duration.fromMillis(5 * 60 * 1000); console.log('Five minutes is ', fiveMinute);

Save the changes, and on running the application, you will have the above fiveMinute duration logged.

You can also use another DateTime object to create a duration using the fromObject method. Here is how the code looks:

let startDate = DateTime.local(); let dur = Duration.fromObject(startDate); console.log('Duration from object is ', dur);

Save the changes, and you will have the duration logged in the browser console.

Wrapping It Up

In this tutorial, you saw how to get started with using the Luxon library for working with date and time in an Angular web project. You learnt how to deal with local time and UTC time, and how to create an interval and duration using Luxon.

For in-depth information on using the Luxon library, I would recommend reading the official documentation.

How was your experience learning to work with Luxon? Do let us know your thoughts in the comments below. 

Categories: Web Design

4 Marketing Strategies With The Best ROI

Webitect - Thu, 02/01/2018 - 07:11

When it comes to marketing, return on investment (ROI) is king. As the easiest and most efficient metric of knowing how effective your campaigns are, ROI has been the cornerstone of formulating marketing plans for some time. If you’ve been struggling to get a solid ROI, check out a few of these strategies to boost your numbers. Social Proof Social proof has been a surefire marketing strategy for centuries, but it has evolved quite a bit in our digital age. This is basically when a customer, celebrity, or peer gives a testimonial or review of your products, services, or general

The post 4 Marketing Strategies With The Best ROI appeared first on Clayton Johnson SEO.

Categories: Web Design

Content Marketing And WordPress: Tips, Plugins, And How To Make An Impact

Smashing Magazine - Thu, 02/01/2018 - 04:00
Content marketing is the practice of creating a piece of content (generally digital) that is both useful and valuable to certain members of your target market(s). This piece of content is generally free, though it may be hidden behind a simple email/lead-capture form, and it usually is meant to be found through search or through free/low-budget distribution methods (think social media, low-cost PPC, a small press release). Some might call this permission marketing, the idea being that your target customers have given you permission to market to them by choosing to access your content.
Categories: Web Design

Debugging JavaScript With A Real Debugger You Did Not Know You Already Have

Smashing Magazine - Thu, 02/01/2018 - 02:00
console.log can tell you a lot about your app, but it can't truly debug your code. For that, you need a full-fledged JavaScript debugger. The new Firefox JavaScript debugger can help you write fast, bug-free code. Here's how it works. In this example, we'll crack open a very simple to-do app with Debugger. Here's the app, based on basic open-source JavaScript frameworks. Open it up in the latest version of Firefox Developer Edition and then launch debugger.
Categories: Web Design

The Ultimate List of Over 35 Free and Paid 80s Fonts

I must say I’ve had a lot of fun looking for fonts to put on this list. The 80s font scene had a lot of variation going for it....

The post The Ultimate List of Over 35 Free and Paid 80s Fonts appeared first on Onextrapixel.

Categories: Web Design

Think Less, Embrace More: Inspiring Desktop Wallpapers For February 2018

Smashing Magazine - Wed, 01/31/2018 - 04:12
Time flies by… The first month of the new year is already behind us, and with February just around the corner, it's time for some fresh inspiration. So how about some wallpapers to tickle your ideas? Wallpapers that are a bit more distinctive as the ones you usually find out there? Well, we've got you covered. As every month since more than nine years already, artists and designers from across the globe once again fired up their favorite illustration tools and got out their paint brushes and cameras to create charming desktop wallpapers that are sure to breathe some fresh life into your desktop.
Categories: Web Design

Exception Handling in Laravel

Tuts+ Code - Web Development - Wed, 01/31/2018 - 04:00

In this article, we're going to explore one of the most important and least discussed features of the Laravel web framework—exception handling. Laravel comes with a built-in exception handler that allows you to report and render exceptions easily and in a friendly manner.

In the first half of the article, we'll explore the default settings provided by the exception handler. In fact, we'll go through the default Handler class in the first place to understand how Laravel handles exceptions.

In the second half of the article, we'll go ahead and see how you could create a custom exception handler that allows you to catch custom exceptions.

Setting Up the Prerequisites

Before we go ahead and dive into the Handler class straight away, let's have a look at a couple of important configuration parameters related to exceptions.

Go ahead and open the config/app.php file. Let's have a close look at the following snippet.

... ... /* |-------------------------------------------------------------------------- | Application Debug Mode |-------------------------------------------------------------------------- | | When your application is in debug mode, detailed error messages with | stack traces will be shown on every error that occurs within your | application. If disabled, a simple generic error page is shown. | */ 'debug' => env('APP_DEBUG', false), ... ...

As the name suggests, if it's set to TRUE, it'll help you to debug errors that are generated by an application. The default value of this variable is set to a value of the APP_DEBUG environment variable in the .env file.

In the development environment, you should set it to TRUE so that you can easily trace errors and fix them. On the other hand, you want to switch it off in the production environment, and it'll display a generic error page in that case.

In addition to displaying errors, Laravel allows you to log errors in the log file. Let's have a quick look at the options available for logging. Again, let's switch to the config/app.php file and have a close look at the following snippet.

... ... 'log' => env('APP_LOG', 'single'), 'log_level' => env('APP_LOG_LEVEL', 'debug'), ... ...

As Laravel uses the Monolog PHP library for logging, you should set the above options in the context of that library.

The default log file is located at storage/logs/laravel.log, and it's sufficient in most cases. On the other hand, the APP_LOG_LEVEL is set to a value that indicates the severity of errors that'll be logged.

So that was a basic introduction to the configuration options available for exceptions and logging.

Next, let's have a look at the default Handler class that comes with the default Laravel application. Go ahead and open the app/Exceptions/Handler.php file.

<?php namespace App\Exceptions; use Exception; use Illuminate\Auth\AuthenticationException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { /** * A list of the exception types that should not be reported. * * @var array */ protected $dontReport = [ \Illuminate\Auth\AuthenticationException::class, \Illuminate\Auth\Access\AuthorizationException::class, \Symfony\Component\HttpKernel\Exception\HttpException::class, \Illuminate\Database\Eloquent\ModelNotFoundException::class, \Illuminate\Session\TokenMismatchException::class, \Illuminate\Validation\ValidationException::class, ]; /** * Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $exception * @return void */ public function report(Exception $exception) { parent::report($exception); } /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { return parent::render($request, $exception); } /** * Convert an authentication exception into an unauthenticated response. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Auth\AuthenticationException $exception * @return \Illuminate\Http\Response */ protected function unauthenticated($request, AuthenticationException $exception) { if ($request->expectsJson()) { return response()->json(['error' => 'Unauthenticated.'], 401); } return redirect()->guest(route('login')); } }

There are two important functions that the handler class is responsible for—reporting and rendering all errors.

Let's have a close look at the report method.

/** * Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $exception * @return void */ public function report(Exception $exception) { parent::report($exception); }

The report method is used to log errors to the log file. At the same time, it's also important to note the dontReport property, which lists all types of exceptions that shouldn't be logged.

Next, let's bring in the render method.

/** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { return parent::render($request, $exception); }

If the report method is used to log or report errors, the render method is used to render errors on a screen. In fact, this method handles what will be displayed to users when the exception occurs.

The render method also allows you to customize a response for different types of exceptions, as we'll see in the next section.

Finally, the unauthenticated method handles the AuthenticationException exception that allows you to decide what will be displayed to users in case they're unauthenticated to access a page they are looking for.

Custom Exception Class

In this section, we'll create a custom exception class that handles exceptions of the CustomException type. The idea behind creating custom exception classes is to easily manage custom exceptions and render custom responses at the same time.

Go ahead and create a file app/Exceptions/CustomException.php with the following contents.

<?php namespace App\Exceptions; use Exception; class CustomException extends Exception { /** * Report the exception. * * @return void */ public function report() { } /** * Render the exception into an HTTP response. * * @param \Illuminate\Http\Request * @return \Illuminate\Http\Response */ public function render($request) { return response()->view( 'errors.custom', array( 'exception' => $this ) ); } }

The important thing to note here is that the CustomException class must extend the core Exception class. For demonstration purposes, we'll only discuss the render method, but of course you could also customize the report method.

As you can see, we're redirecting users to the errors.custom error page in our case. In that way, you can implement custom error pages for specific types of exceptions.

Of course, we need to create an associated view file at resources/views/errors/custom.blade.php.

Exception details: <b>{{ $exception->getMessage() }}</b>

That's a pretty simple view file that displays an error message, but of course you could design it the way you want it to be.

We also need to make changes in the render method of the app/Exceptions/Handler.php file so that our custom exception class can be invoked. Let's replace the render method with the following contents in the app/Exceptions/Handler.php file.

... ... /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { if ($exception instanceof \App\Exceptions\CustomException) { return $exception->render($request); } return parent::render($request, $exception); } ... ...

As you can see, we are checking the type of an exception in the render method in the first place. If the type of an exception is \App\Exceptions\CustomException, we call the render method of that class.

So everything is in place now. Next, let's go ahead and create a controller file at app/Http/Controllers/ExceptionController.php so we can test our custom exception class.

<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; class ExceptionController extends Controller { public function index() { // something went wrong and you want to throw CustomException throw new \App\Exceptions\CustomException('Something Went Wrong.'); } }

Of course, you need to add an associated route in the routes/web.php as shown in the following snippet.

// Exception routes Route::get('exception/index', 'ExceptionController@index');

And with that in place, you can run the http://your-laravel-site.com/exception/index URL to see if it works as expected. It should display the errors.custom view as per our configuration.

So that's how you are supposed to handle custom exceptions in Laravel. And that brings us to the end of this article—I hope you've enjoyed it!


Today, we went through the exception handling feature in Laravel. At the beginning of the article, we explored the basic configuration provided by Laravel in order to render and report exceptions. Further, we had a brief look at the default exception handler class.

In the second half of the article, we prepared a custom exception handler class that demonstrated how you could handle custom exceptions in your application.

For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.

I would love to hear from you in the form of queries and suggestions!

Categories: Web Design

A Comprehensive Guide To Product Design

Smashing Magazine - Wed, 01/31/2018 - 03:00
(This is a sponsored article.) What is a product? Until recently, the term was used only in relation to something material and often found in a retail store. Nowadays, it is coming to mean digital products as well. Apps and websites are modern products. When it comes to building great products, design is the most important “feature.” We’ve moved into the stage where product design dominates — it’s what sets companies apart and gives a real edge over competitors.
Categories: Web Design