Publishing an ASP.NET Core website to a cheap Linux VM host

A little Linux VM on Azure is like $13 a month. You can get little Linux machines all over for between $10-15 a month. On Linode they are about $10 a month so I figured it would be interesting to setup an ASP.NET Core website running on .NET Core. As you may know, .NET Core is free, open source, cross platform and runs basically everywhere.

Step 0 – Get a cheap host

I went to Linode (or anywhere) and got the cheapest Linux machine they offered. In this case it’s an Ubuntu 14.04 LTS Profile, 640bit, 4.6.5 Kernel.

I signed up for a tiny VM at Linode

Since I’m on Windows but I want to SSH into this Linux machine I’ll need a SSH client. There’s a bunch of options.

Step 0.5 – Setup a user that isn’t root

It’s always a good idea to avoid being root. After logging into the system as root, I made a new user and give them sudo (super user do):

adduser scott
usermod -aG sudo scott

Then I’ll logout and go back in as scott.

Step 1 – Get .NET Core on your Linux Machine

Head over to http://dot.net to get .NET Core and follow the instructions. There’s at least 8 Linuxes supported in 6 flavors so you should have no trouble. I followed the Ubuntu instructions.

To make sure it works after you’ve set it up, make a quick console app like this and run it.

mkdir testapp
cd testapp
dotnet new
dotnet restore
dotnet run

If it runs, then you’ve got .NET Core installed and you can move on to making a web app and exposing it to the internet.

NOTE: If “dotnet restore” fails with a segmentation fault, you may be running into this issue with some 64-bit Linux Kernels. Here’s commands to fix it that worked for me on Ubuntu 14.04 when I hit this. The fix has been released as a NuGet now but it will be included with the next minor release of .NET Core, but if you ever need to manually update the CoreCLR you can.

Step 2 – Make an ASP.NET Core website

You can make an ASP.NET Core website that is very basic and very empty and that’s OK. You can also get Yeoman and use the ASP.NET yeoman-based generators to get more choices. There is also the great ASP.NET MVC Boilerplate project for Visual Studio.

Or you can just start with:

dotnet new -t web

Today, this default site uses npm, gulp, and bower to manage JavaScript and CSS dependencies. In the future there will be options that don’t require as much extra stuff but for now, in order to dotnet restore this site I’ll need npm and what not so I’ll do this to get node, npm, etc.

sudo install npm
sudo npm install gulp
sudo npm install bower

Now I can dotnet restore easily and run my web app to test. It will startup on localhost:5000 usually.

$ dotnet restore
$ dotnet run
[email protected]:~/dotnettest$ dotnet run
Project dotnettest (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using '/home/scott/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /home/scott/dotnettest
Now listening on: http://localhost:5000

Of course, having something startup on localhost:5000 doesn’t help me as I’m over here at home so I can’t test a local website like this. I want to expose this site (via a port) to the outside world. I want something like http://mysupermachine -> inside my machine -> localhost:5000.

Step 3 – Expose your web app to the outside.

I could tell Kestrel – that’s the .NET Web Server – to expose itself to Port 80, although you usually want to have another process between you and the outside world.

You can do this a few ways. You can open open Program.cs with a editor like “pico” and add a .UseUrls() call to the WebHostBuilder like this.

var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:80")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

Here the * binds to all the network adapters and it listens on Port 80. Putting http://0.0.0.0:80 also works.

You might have permission issues doing this and need to elevate the dotnet process and webserver which is also a problem so let’s just keep it at a high internal port and reverse proxy the traffic with something like Nginx or Apache. We’ll pull out the hard-coded port from the code and change the Program.cs to use a .json config file.

public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();

var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

host.Run();
}

The hosting.json file is just this:

{
"server.urls": "http://localhost:5123"
}

We can also use “AddCommandLine(args) instead of “AddJsonFile()” and pass in –server.urls=http://*:5123 on the command line. It’s up to you. You can also use the ASPNETCORE_URLS environment variable.

NOTE: I’m doing this work a folder under my home folder ~ or now. I’ll later compile and “publish” this website to something like /var/dotnettest when I want it seen.

Step 4 – Setup a Reverse Proxy like Nginx

I’m following the detailed instructions at the ASP.NET Core Docs site called “Publish to a Linux Production Environment.” (All the docs are on GitHub as well)

I’m going to bring in Nginx and start it.

sudo apt-get install nginx
sudo service nginx start

I’m going to change the default Nginx site to point to my (future) running ASP.NET Core web app. I’ll open and change /etc/nginx/sites-available/default and make it look like this. Note the port number. Nginx is a LOT more complex than this and has a lot of nuance, so when you are ready to go into Super Official Production, be sure to explore what the perfect Nginx Config File looks like and change it to your needs.

server {
listen 80;
location / {
proxy_pass http://localhost:5123;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Then we’ll check it and reload the config.

sudo nginx -t 
sudo nginx -s reload

Step 5 – Keep your website running

The website isn’t up and running on localhost:5123 yet (unless you’ve run it yourself and kept it running!) so we’ll need an app or a monitor to run it and keep it running. There’s an app called Supervisor that is good at that so I’ll add it.

sudo apt-get install supervisor

Here is where you/we/I/errbody needs to get the paths and names right, so be aware. I’m over in ~/testapp or something. I need to publish my site into a final location so I’m going to run dotnet publish, then copy the reuslts into /var/dotnettest where it will live.

dotnet publish
publish: Published to /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish
sudo cp -a /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish /var/dotnettest

Now I’m going to make a file (again, I use pico because I’m not as awesome as emacs or vim) called /src/supervisor/conf.d/dotnettest.conf to start my app and keep it running:

[program:dotnettest]
command=/usr/bin/dotnet /var/dotnettest/dotnettest.dll --server.urls:http://*:5123
directory=/var/dotnettest/
autostart=true
autorestart=true
stderr_logfile=/var/log/dotnettest.err.log
stdout_logfile=/var/log/dotnettest.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data
stopsignal=INT

Now we start and stop Supervisor and watch/tail its logs to see our app startup!

sudo service supervisor stop
sudo service supervisor start
sudo tail -f /var/log/supervisor/supervisord.log
#and the application logs if you like
sudo tail -f /var/log/dotnettest.out.log

If all worked out (if it didn’t, it’ll be a name or a path so keep trying!) you’ll see the supervisor log with dotnet starting up, running your app.

Hey it's dotnet on linux

Remember the relationships.

  • Dotnet – runs your website
  • Nginx or Apache – Listens on Port 80 and forwards HTTP calls to your website
  • Supervisor – Keeps your app running

Next, I might want to setup a continuous integration build, or SCP/SFTP to handle deployment of my app. That way I can develop locally and push up to my Linux machine.

Hey it's my ASP.NET Core app on Linux

Of course, there are a dozen other ways to publish an ASP.NET Core site, not to mention Docker. I’ll post about Docker another time, but for now, I was able to get my ASP.NET Core website published to a cheap $10 host in less than an hour. You can use the same tools to manage a .NET Core site that you use to manage any site be it PHP, nodejs, Ruby, or whatever makes you happy.


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

A little Linux VM on Azure is like $13 a month. You can get little Linux machines all over for between $10-15 a month. On Linode they are about $10 a month so I figured it would be interesting to setup an ASP.NET Core website running on .NET Core. As you may know, .NET Core is free, open source, cross platform and runs basically everywhere.

Step 0 - Get a cheap host

I went to Linode (or anywhere) and got the cheapest Linux machine they offered. In this case it's an Ubuntu 14.04 LTS Profile, 640bit, 4.6.5 Kernel.

I signed up for a tiny VM at Linode

Since I'm on Windows but I want to SSH into this Linux machine I'll need a SSH client. There's a bunch of options.

Step 0.5 - Setup a user that isn't root

It's always a good idea to avoid being root. After logging into the system as root, I made a new user and give them sudo (super user do):

adduser scott

usermod -aG sudo scott

Then I'll logout and go back in as scott.

Step 1 - Get .NET Core on your Linux Machine

Head over to http://dot.net to get .NET Core and follow the instructions. There's at least 8 Linuxes supported in 6 flavors so you should have no trouble. I followed the Ubuntu instructions.

To make sure it works after you've set it up, make a quick console app like this and run it.

mkdir testapp

cd testapp
dotnet new
dotnet restore
dotnet run

If it runs, then you've got .NET Core installed and you can move on to making a web app and exposing it to the internet.

NOTE: If "dotnet restore" fails with a segmentation fault, you may be running into this issue with some 64-bit Linux Kernels. Here's commands to fix it that worked for me on Ubuntu 14.04 when I hit this. The fix has been released as a NuGet now but it will be included with the next minor release of .NET Core, but if you ever need to manually update the CoreCLR you can.

Step 2 - Make an ASP.NET Core website

You can make an ASP.NET Core website that is very basic and very empty and that's OK. You can also get Yeoman and use the ASP.NET yeoman-based generators to get more choices. There is also the great ASP.NET MVC Boilerplate project for Visual Studio.

Or you can just start with:

dotnet new -t web

Today, this default site uses npm, gulp, and bower to manage JavaScript and CSS dependencies. In the future there will be options that don't require as much extra stuff but for now, in order to dotnet restore this site I'll need npm and what not so I'll do this to get node, npm, etc.

sudo install npm

sudo npm install gulp
sudo npm install bower

Now I can dotnet restore easily and run my web app to test. It will startup on localhost:5000 usually.

$ dotnet restore

$ dotnet run
[email protected]:~/dotnettest$ dotnet run
Project dotnettest (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using '/home/scott/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /home/scott/dotnettest
Now listening on: http://localhost:5000

Of course, having something startup on localhost:5000 doesn't help me as I'm over here at home so I can't test a local website like this. I want to expose this site (via a port) to the outside world. I want something like http://mysupermachine -> inside my machine -> localhost:5000.

Step 3 - Expose your web app to the outside.

I could tell Kestrel - that's the .NET Web Server - to expose itself to Port 80, although you usually want to have another process between you and the outside world.

You can do this a few ways. You can open open Program.cs with a editor like "pico" and add a .UseUrls() call to the WebHostBuilder like this.

var host = new WebHostBuilder()

.UseKestrel()
.UseUrls("http://*:80")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

Here the * binds to all the network adapters and it listens on Port 80. Putting http://0.0.0.0:80 also works.

You might have permission issues doing this and need to elevate the dotnet process and webserver which is also a problem so let's just keep it at a high internal port and reverse proxy the traffic with something like Nginx or Apache. We'll pull out the hard-coded port from the code and change the Program.cs to use a .json config file.

public static void Main(string[] args)

{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();

var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

host.Run();
}

The hosting.json file is just this:

{

"server.urls": "http://localhost:5123"
}

We can also use "AddCommandLine(args) instead of "AddJsonFile()" and pass in --server.urls=http://*:5123 on the command line. It's up to you. You can also use the ASPNETCORE_URLS environment variable.

NOTE: I'm doing this work a folder under my home folder ~ or now. I'll later compile and "publish" this website to something like /var/dotnettest when I want it seen.

Step 4 - Setup a Reverse Proxy like Nginx

I'm following the detailed instructions at the ASP.NET Core Docs site called "Publish to a Linux Production Environment." (All the docs are on GitHub as well)

I'm going to bring in Nginx and start it.

sudo apt-get install nginx

sudo service nginx start

I'm going to change the default Nginx site to point to my (future) running ASP.NET Core web app. I'll open and change /etc/nginx/sites-available/default and make it look like this. Note the port number. Nginx is a LOT more complex than this and has a lot of nuance, so when you are ready to go into Super Official Production, be sure to explore what the perfect Nginx Config File looks like and change it to your needs.

server {

listen 80;
location / {
proxy_pass http://localhost:5123;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Then we'll check it and reload the config.

sudo nginx -t 

sudo nginx -s reload

Step 5 - Keep your website running

The website isn't up and running on localhost:5123 yet (unless you've run it yourself and kept it running!) so we'll need an app or a monitor to run it and keep it running. There's an app called Supervisor that is good at that so I'll add it.

sudo apt-get install supervisor

Here is where you/we/I/errbody needs to get the paths and names right, so be aware. I'm over in ~/testapp or something. I need to publish my site into a final location so I'm going to run dotnet publish, then copy the reuslts into /var/dotnettest where it will live.

dotnet publish

publish: Published to /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish
sudo cp -a /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish /var/dotnettest

Now I'm going to make a file (again, I use pico because I'm not as awesome as emacs or vim) called /src/supervisor/conf.d/dotnettest.conf to start my app and keep it running:

[program:dotnettest]

command=/usr/bin/dotnet /var/dotnettest/dotnettest.dll --server.urls:http://*:5123
directory=/var/dotnettest/
autostart=true
autorestart=true
stderr_logfile=/var/log/dotnettest.err.log
stdout_logfile=/var/log/dotnettest.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data
stopsignal=INT

Now we start and stop Supervisor and watch/tail its logs to see our app startup!

sudo service supervisor stop

sudo service supervisor start
sudo tail -f /var/log/supervisor/supervisord.log
#and the application logs if you like
sudo tail -f /var/log/dotnettest.out.log

If all worked out (if it didn't, it'll be a name or a path so keep trying!) you'll see the supervisor log with dotnet starting up, running your app.

Hey it's dotnet on linux

Remember the relationships.

  • Dotnet - runs your website
  • Nginx or Apache - Listens on Port 80 and forwards HTTP calls to your website
  • Supervisor - Keeps your app running

Next, I might want to setup a continuous integration build, or SCP/SFTP to handle deployment of my app. That way I can develop locally and push up to my Linux machine.

Hey it's my ASP.NET Core app on Linux

Of course, there are a dozen other ways to publish an ASP.NET Core site, not to mention Docker. I'll post about Docker another time, but for now, I was able to get my ASP.NET Core website published to a cheap $10 host in less than an hour. You can use the same tools to manage a .NET Core site that you use to manage any site be it PHP, nodejs, Ruby, or whatever makes you happy.


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.



© 2016 Scott Hanselman. All rights reserved.
     

Beginner’s Guide to Troubleshooting WordPress Errors (Step by Step)

Are you encountering a common WordPress error on your site? Do you want to troubleshoot these WordPress errors on your own? Most of these errors can be solved by following easy troubleshooting steps. In this beginner’s guide, we will show you how to troubleshoot WordPress… Read More »

The post Beginner’s Guide to Troubleshooting WordPress Errors (Step by Step) appeared first on WPBeginner.

Are you encountering a common WordPress error on your site? Do you want to troubleshoot these WordPress errors on your own? Most of these errors can be solved by following easy troubleshooting steps. In this beginner’s guide, we will show you how to troubleshoot WordPress errors one step at a time.

Troubleshooting WordPress errors

1. Create a Complete Backup of Your WordPress Site

First thing you should do is to create a complete backup of your WordPress site. If you were already using a WordPress backup plugin, then make sure that you have a recent backup safely stored somewhere.

If you were not using a backup plugin, then you should start using one immediately. However, in case you don’t have access to the admin area of your WordPress site, then you will need to manually backup your database and files.

Backups allow you to restore your WordPress site easily when something goes wrong. They are your first and most important defence against security threats, hacking, and data loss.

2. Deactivate All Plugins Installed on Your Website

Most of the times errors are caused by a plugins conflicting with each other, your theme, or the WordPress core. Deactivating all WordPress plugins on your site will most likely solve the problem. You can then find out which plugin was causing the issue by activating plugins one by one on your site.

If you have access to the admin area of your WordPress site, then simply head over to the plugins page.

Select and deactivate all plugins in WordPress

First you need to select all plugins, and then select ‘Deactivate’ from ‘Bulk Actions’ drop down menu. Click on the Apply button to deactivate all selected plugins.

If you do not have access to the admin area, then you will need to use FTP or phpMyAdmin to deactivate all plugins.

Simply connect to your website using an FTP client. If you haven’t used FTP before, then you may want to see our how to use FTP to upload files to WordPress.

Navigate to the wp-content folder and rename plugins folder to “plugin.deactivate”.

Rename plugins folder using FTP

For more detailed instructions, see our article on how to deactivate all plugins when not able to access wp-admin.

3. Switch to a Default WordPress Theme

Sometimes your WordPress theme can cause issues on your site. You can easily find out if your theme is causing an issue by switching to a default WordPress theme like Twenty Sixteen or Twenty Fifteen.

Head over to Appearance » Themes page and then click on the Activate button next to a default theme.

Switch to a default WordPress theme

However, if you don’t have access to the admin area of your WordPress site, then you will need to use FTP to switch theme.

Connect to your website using an FTP client and then navigate to /wp-content/themes/ folder. Download your current active theme as a backup to your Desktop.

After that you need to delete all themes except a default WordPress theme like TwentySixteen. Since your active theme will no longer be available, WordPress will now automatically switch to using the default theme available.

If your theme was causing the issue, then you should be able to log in to your WordPress site now.

4. Refresh Permalinks

WordPress uses SEO friendly URL structure or Permalinks. Sometimes the permalink structure is not updated or configured properly, which may result in unexpected 404 errors on your site.

You can easily refresh permalinks without changing anything on your WordPress site. Visit Settings » Permalinks page and click on ‘Save Changes’ button without changing anything.

Update permalinks in WordPress

5. Backup and Delete .htaccess File

A corrupt .htaccess file is often the cause of the internal server error.

First you need to connect to your website using an FTP client. The .htaccess file is located in your site’s root directory.

Since it is a hidden file, you may need to force your FTP client to show hidden files. See our article on why you can’t find .htaccess file on your WordPress site

You need to download the .htaccess file to your computer as a backup, and then delete it from your web server.

You can now try to login to your WordPress site and go to Settings » Permalinks page. Click on the Save Changes button to refresh your permalinks and to regenerate a new .htaccess file for your site.

6. Fix WordPress Site URL

Having incorrect settings for WordPress URL and Site URL options can also cause redirect issues, 404 errors, and some other common issues.

WordPress URL and Site URL options can be changed from admin area by visiting Settings » General page.

Changing WordPress Address and Site Address options from admin area

Make sure that both URLs are exactly the same.

If you do not have access to the admin area of your WordPress site, then you can change these URLs using FTP. There are two ways to do that using FTP:

Update WordPress URL and Site URL Settings in wp-config.php File

Once connected to your website using an FTP client, locate wp-config.php file. Now you need to edit this file in a text editor like Notepad.

Go to the line that says /* That's all, stop editing! Happy blogging. */, and just before it, add this code:

define('WP_HOME','http://example.com');
define('WP_SITEURL','http://example.com');

Don’t forget to replace example.com with your own domain name. Now save your changes and upload the file back to your server.

Update URLs Using functions.php File

You can also update URLs using your theme’s functions.php file.

Open your FTP client and navigate to /wp-content/themes/ folder. Open your current active theme’s folder and locate functions.php file inside it. Now you will need to edit the functions.php file in a text editor like Notepad.

Simply add these lines at the bottom of the functions file:

update_option( 'siteurl', 'http://example.com' );
update_option( 'home', 'http://example.com' );

Don’t forget to change WordPress URLs from the settings page after you login to your site. Once you have added them on the settings page, you need to delete these lines from your theme’s functions file.

7. Check Reading Settings

If your newly created WordPress site is not indexed by search engines, then this is the first thing that you should do.

Login to your WordPress site and go to Settings » Reading page. Scroll down to the bottom of the page and make sure that the box next to ‘Search Engine Visibility’ is unchecked.

Search engine visibility

This option allows you to discourage search engines from showing your website in search. It is used by webmasters when they are working on a website which is not ready to be live. Sometimes you can accidentally check this setting and forget about it.

Make sure that this option is unchecked when your website is ready to go live.

8. Troubleshooting Email Issues

Many WordPress hosting providers do not have mail settings properly configured. This stops you and your users to receive emails from WordPress.

If you are using a contact form plugin, then you will not be able to receive those emails as well. You will also not receive any WordPress notifications.

See our complete step by step instructions in our article on how to fix WordPress not sending email issue.

9. Scanning for Malware and Backdoors

If you suspect that your WordPress site is affected with malware, then you should scan your website with Sucuri. It is the best website security monitoring service for WordPress site owners.

See our case study of how Sucuri helped us block 450,000 WordPress attacks in 3 months.

For more detailed instructions, see our guide on how to scan your WordPress site for potentially malicious code.

Getting Better Support

After following the above mentioned troubleshooting steps, you would be able to fix many of the most common WordPress errors. However, if the problem persists, then you can seek further support.

WordPress is a community software, so you can get help from the community by posting in WordPress support forums. Here is how to write a better support request:

  • Be polite and nice. No matter how upset or frustrated you are, do not use harsh language.
  • Mention your problem briefly.
  • Describe troubleshooting steps you have taken so far.
  • Uplaod screenshots on a cloud image sharing service, and then add the links in your support thread.

For more on this topic, take a look at our guide on how to properly ask for WordPress support and get it.

We hope this article helped you learn how to troubleshoot WordPress errors. You may also want to see our list of 14 most common WordPress errors and how to fix them.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post Beginner’s Guide to Troubleshooting WordPress Errors (Step by Step) appeared first on WPBeginner.

How to Show Total Number of Registered Users in WordPress

Have you ever wanted to show the total number of registered users on your WordPress site? Social proof like showing the number of registered users on your site, encourages others to register as well. In this article, we will show you how to show total… Read More »

The post How to Show Total Number of Registered Users in WordPress appeared first on WPBeginner.

Have you ever wanted to show the total number of registered users on your WordPress site? Social proof like showing the number of registered users on your site, encourages others to register as well. In this article, we will show you how to show total number of registered users in WordPress.

How to Show Total Number of Registered Users in WordPress

Method 1: Show Registered User Count Using a WordPress Plugin

First thing you need to do is install and activate the Simple Blog Stats plugin. For more details, see our step by step guide on how to install a WordPress plugin.

Upon activation, you need to visit Settings » Simple Blog Stats page to configure plugin settings.

Settings page for Simple Blog Stats

This plugin allows you to show different stats from your WordPress site. You need to click on the shortcodes tab to expand it and then scroll down to the ‘number of users’ row.

Users shortcode settings

You will see the shortcode [sbs_users] with two text fields on both sides. These text fields contain HTML the plugin will add before and after the number of users.

By default, the shortcode will output HTML like this:

<span class="sbs-count-users">856</span>

If you are unsure, then just copy the shortcode [sbs_users] and click on the save settings button.

You can now add this shortcode to any WordPress post or page. You can also add it to a sidebar widget. If the shortcode does not work in the widget, then follow instructions in our guide on how to use shortcodes in your WordPress sidebar widget.

Method 2: Manually Show Number of Registered Users in WordPress with Code

This method requires you to add code to your WordPress site. If you haven’t done this before, then see our beginner’s guide on pasting snippets from web into WordPress.

You need to add the following code to your theme’s functions.php file or a site-specific plugin.

// Function to return user count
function wpb_user_count() { 
$usercount = count_users();
$result = $usercount['total_users']; 
return $result; 
} 
// Creating a shortcode to display user count
add_shortcode('user_count', 'wpb_user_count');

This code creates shortcode [user_count] which you can use in your WordPress posts, pages, or a sidebar widget to display the user count.

The function does not add any HTML formatting to the user count and simply returns the number. You may want to wrap the shortcode around HTML to use CSS or basic HTML formatting. For example:

<p>Join <strong>[user_count]</strong> other users who share your interest:</p>

Here is how it looked on our demo site:

Showing total number of users in WordPress widget

Note: We added a free signup button that redirected to a custom WordPress user registration page.

That’s all, we hope this article helped you learn how to show the total number of registered users in WordPress. You may also want to see our guide on how to moderate new user registrations in WordPress.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Show Total Number of Registered Users in WordPress appeared first on WPBeginner.

What is Serverless Computing? Exploring Azure Functions

There’s a lot of confusing terms in the Cloud space. And that’s not counting the term “Cloud.” 😉

  • IaaS (Infrastructure as a Services) – Virtual Machines and stuff on demand.
  • PaaS (Platform as a Service) – You deploy your apps but try not to think about the Virtual Machines underneath. They exist, but we pretend they don’t until forced.
  • SaaS (Software as a Service) – Stuff like Office 365 and Gmail. You pay a subscription and you get email/whatever as a service. It Just Works.

“Serverless Computing” doesn’t really mean there’s no server. Serverless means there’s no server you need to worry about. That might sound like PaaS, but it’s higher level that than.

Serverless Computing is like this – Your code, a slider bar, and your credit card. You just have your function out there and it will scale as long as you can pay for it. It’s as close to “cloudy” as The Cloud can get.

Serverless Computing is like this. Your code, a slider bar, and your credit card.

With Platform as a Service, you might made a Node or C# app, check it into Git, deploy it to a Web Site/Application, and then you’ve got an endpoint. You might scale it up (get more CPU/Memory/Disk) or out (have 1, 2, n instances of the Web App) but it’s not seamless. It’s totally cool, to be clear, but you’re always aware of the servers.

New cloud systems like Amazon Lambda and Azure Functions have you upload some code and it’s running seconds later. You can have continuous jobs, functions that run on a triggered event, or make Web APIs or Webhooks that are just a function with a URL.

I’m going to see how quickly I can make a Web API with Serverless Computing.

I’ll go to http://functions.azure.com and make a new function. If you don’t have an account you can sign up free.

Getting started with Azure Functions

You can make a function in JavaScript or C#.

Getting started with Azure Functions - Create This Function

Once you’re into the Azure Function Editor, click “New Function” and you’ve got dozens of templates and code examples for things like:

  • Find a face in an image and store the rectangle of where the face is.
  • Run a function and comment on a GitHub issue when a GitHub webhook is triggered
  • Update a storage blob when an HTTP Request comes in
  • Load entities from a database or storage table

I figured I’d change the first example. It is a trigger that sees an image in storage, calls a cognitive services API to get the location of the face, then stores the data. I wanted to change it to:

  • Take an image as input from an HTTP Post
  • Draw a rectangle around the face
  • Return the new image

You can do this work from Git/GitHub but for easy stuff I’m literally doing it all in the browser. Here’s what it looks like.

Azure Functions can be done in the browser

I code and iterate and save and fail fast, fail often. Here’s the starter code I based it on. Remember, that this is a starter function that runs on a triggered event, so note its Run()…I’m going to change this.

#r "Microsoft.WindowsAzure.Storage"
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.IO; 
public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    
    string result = await CallVisionAPI(image); //STREAM
    log.Info(result); 
    if (String.IsNullOrEmpty(result))
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    foreach (Face face in imageData.Faces)
    {
        var faceRectangle = face.FaceRectangle;
        faceRectangle.RowKey = Guid.NewGuid().ToString();
        faceRectangle.PartitionKey = "Functions";
        faceRectangle.ImageFile = name + ".jpg";
        await outTable.AddAsync(faceRectangle); 
    }
    return req.CreateResponse(HttpStatusCode.OK, "Nice Job");  
}
static async Task<string> CallVisionAPI(Stream image)
{
    using (var client = new HttpClient())
    {
        var content = new StreamContent(image);
        var url = "https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures=Faces";
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));
        content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        var httpResponse = await client.PostAsync(url, content);
        if (httpResponse.StatusCode == HttpStatusCode.OK){
            return await httpResponse.Content.ReadAsStringAsync();
        }
    }
    return null;
}
public class ImageData {
    public List<Face> Faces { get; set; }
}
public class Face {
    public int Age { get; set; }
    public string Gender { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
}
public class FaceRectangle : TableEntity {
    public string ImageFile { get; set; }
    public int Left { get; set; }
    public int Top { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

GOAL: I’ll change this Run() and make this listen for an HTTP request that contains an image, read the image that’s POSTed in (ya, I know, no validation), draw rectangle around detected faces, then return a new image.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) {
var image = await req.Content.ReadAsStreamAsync();

As for the body of this function, I’m 20% sure I’m using too many MemoryStreams but they are getting disposed so take this code as a initial proof of concept. However, I DO need at least the two I have. Regardless, happy to chat with those who know more, but it’s more subtle than even I thought. That said, basically call out to the API, get back some face data that looks like this:

2016-08-26T23:59:26.741 {"requestId":"8be222ff-98cc-4019-8038-c22eeffa63ed","metadata":{"width":2808,"height":1872,"format":"Jpeg"},"faces":[{"age":41,"gender":"Male","faceRectangle":{"left":1059,"top":671,"width":466,"height":466}},{"age":41,"gender":"Male","faceRectangle":{"left":1916,"top":702,"width":448,"height":448}}]}

Then take that data and DRAW a Rectangle over the faces detected.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    MemoryStream mem = new MemoryStream();
    image.CopyTo(mem); //make a copy since one gets destroy in the other API. Lame, I know.
    image.Position = 0;
    mem.Position = 0;
    
    string result = await CallVisionAPI(image); 
    log.Info(result); 
    if (String.IsNullOrEmpty(result)) {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    MemoryStream outputStream = new MemoryStream();
    using(Image maybeFace = Image.FromStream(mem, true))
    {
        using (Graphics g = Graphics.FromImage(maybeFace))
        {
            Pen yellowPen = new Pen(Color.Yellow, 4);
            foreach (Face face in imageData.Faces)
            {
                var faceRectangle = face.FaceRectangle;
                g.DrawRectangle(yellowPen, 
                    faceRectangle.Left, faceRectangle.Top, 
                    faceRectangle.Width, faceRectangle.Height);
            }
        }
        maybeFace.Save(outputStream, ImageFormat.Jpeg);
    }
    
    var response = new HttpResponseMessage()
    {
        Content = new ByteArrayContent(outputStream.ToArray()),
        StatusCode = HttpStatusCode.OK,
    };
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

 

Now I go into Postman and POST an image to my new Azure Function endpoint. Here I uploaded a flattering picture of me and unflattering picture of The Oatmeal. He’s pretty in real life just NOT HERE. 😉

Image Recognition with Azure Functions

So in just about 15 min with no idea and armed with just my browser, Postman (also my browser), Google/StackOverflow, and Azure Functions I’ve got a backend proof of concept.

Azure Functions supports Node.js, C#, F#, Python, PHP *and* Batch, Bash, and PowerShell, which really opens it up to basically anyone. You can use them for anything when you just want a function (or more) out there on the web. Send stuff to Slack, automate your house, update GitHub issues, act as a Webhook, etc. There’s some great 3d party Azure Functions sample code in this GitHub repo as well. Inputs can be from basically anywhere and outputs can be basically anywhere. If those anywheres are also cloud services like Tables or Storage, you’ve got a “serverless backed” that is easy to scale.

I’m still learning, but I can see when I’d want a VM (total control) vs a Web App (near total control) vs a “Serverless” Azure Function (less control but I didn’t need it anyway, just wanted a function in the cloud.)


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

There's a lot of confusing terms in the Cloud space. And that's not counting the term "Cloud." ;)

  • IaaS (Infrastructure as a Services) - Virtual Machines and stuff on demand.
  • PaaS (Platform as a Service) - You deploy your apps but try not to think about the Virtual Machines underneath. They exist, but we pretend they don't until forced.
  • SaaS (Software as a Service) - Stuff like Office 365 and Gmail. You pay a subscription and you get email/whatever as a service. It Just Works.

"Serverless Computing" doesn't really mean there's no server. Serverless means there's no server you need to worry about. That might sound like PaaS, but it's higher level that than.

Serverless Computing is like this - Your code, a slider bar, and your credit card. You just have your function out there and it will scale as long as you can pay for it. It's as close to "cloudy" as The Cloud can get.

Serverless Computing is like this. Your code, a slider bar, and your credit card.

With Platform as a Service, you might made a Node or C# app, check it into Git, deploy it to a Web Site/Application, and then you've got an endpoint. You might scale it up (get more CPU/Memory/Disk) or out (have 1, 2, n instances of the Web App) but it's not seamless. It's totally cool, to be clear, but you're always aware of the servers.

New cloud systems like Amazon Lambda and Azure Functions have you upload some code and it's running seconds later. You can have continuous jobs, functions that run on a triggered event, or make Web APIs or Webhooks that are just a function with a URL.

I'm going to see how quickly I can make a Web API with Serverless Computing.

I'll go to http://functions.azure.com and make a new function. If you don't have an account you can sign up free.

Getting started with Azure Functions

You can make a function in JavaScript or C#.

Getting started with Azure Functions - Create This Function

Once you're into the Azure Function Editor, click "New Function" and you've got dozens of templates and code examples for things like:

  • Find a face in an image and store the rectangle of where the face is.
  • Run a function and comment on a GitHub issue when a GitHub webhook is triggered
  • Update a storage blob when an HTTP Request comes in
  • Load entities from a database or storage table

I figured I'd change the first example. It is a trigger that sees an image in storage, calls a cognitive services API to get the location of the face, then stores the data. I wanted to change it to:

  • Take an image as input from an HTTP Post
  • Draw a rectangle around the face
  • Return the new image

You can do this work from Git/GitHub but for easy stuff I'm literally doing it all in the browser. Here's what it looks like.

Azure Functions can be done in the browser

I code and iterate and save and fail fast, fail often. Here's the starter code I based it on. Remember, that this is a starter function that runs on a triggered event, so note its Run()...I'm going to change this.

#r "Microsoft.WindowsAzure.Storage"
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.IO; 
public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    
    string result = await CallVisionAPI(image); //STREAM
    log.Info(result); 
    if (String.IsNullOrEmpty(result))
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    foreach (Face face in imageData.Faces)
    {
        var faceRectangle = face.FaceRectangle;
        faceRectangle.RowKey = Guid.NewGuid().ToString();
        faceRectangle.PartitionKey = "Functions";
        faceRectangle.ImageFile = name + ".jpg";
        await outTable.AddAsync(faceRectangle); 
    }
    return req.CreateResponse(HttpStatusCode.OK, "Nice Job");  
}
static async Task<string> CallVisionAPI(Stream image)
{
    using (var client = new HttpClient())
    {
        var content = new StreamContent(image);
        var url = "https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures=Faces";
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));
        content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        var httpResponse = await client.PostAsync(url, content);
        if (httpResponse.StatusCode == HttpStatusCode.OK){
            return await httpResponse.Content.ReadAsStringAsync();
        }
    }
    return null;
}
public class ImageData {
    public List<Face> Faces { get; set; }
}
public class Face {
    public int Age { get; set; }
    public string Gender { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
}
public class FaceRectangle : TableEntity {
    public string ImageFile { get; set; }
    public int Left { get; set; }
    public int Top { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

GOAL: I'll change this Run() and make this listen for an HTTP request that contains an image, read the image that's POSTed in (ya, I know, no validation), draw rectangle around detected faces, then return a new image.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) {

var image = await req.Content.ReadAsStreamAsync();

As for the body of this function, I'm 20% sure I'm using too many MemoryStreams but they are getting disposed so take this code as a initial proof of concept. However, I DO need at least the two I have. Regardless, happy to chat with those who know more, but it's more subtle than even I thought. That said, basically call out to the API, get back some face data that looks like this:

2016-08-26T23:59:26.741 {"requestId":"8be222ff-98cc-4019-8038-c22eeffa63ed","metadata":{"width":2808,"height":1872,"format":"Jpeg"},"faces":[{"age":41,"gender":"Male","faceRectangle":{"left":1059,"top":671,"width":466,"height":466}},{"age":41,"gender":"Male","faceRectangle":{"left":1916,"top":702,"width":448,"height":448}}]}

Then take that data and DRAW a Rectangle over the faces detected.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    MemoryStream mem = new MemoryStream();
    image.CopyTo(mem); //make a copy since one gets destroy in the other API. Lame, I know.
    image.Position = 0;
    mem.Position = 0;
    
    string result = await CallVisionAPI(image); 
    log.Info(result); 
    if (String.IsNullOrEmpty(result)) {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    MemoryStream outputStream = new MemoryStream();
    using(Image maybeFace = Image.FromStream(mem, true))
    {
        using (Graphics g = Graphics.FromImage(maybeFace))
        {
            Pen yellowPen = new Pen(Color.Yellow, 4);
            foreach (Face face in imageData.Faces)
            {
                var faceRectangle = face.FaceRectangle;
                g.DrawRectangle(yellowPen, 
                    faceRectangle.Left, faceRectangle.Top, 
                    faceRectangle.Width, faceRectangle.Height);
            }
        }
        maybeFace.Save(outputStream, ImageFormat.Jpeg);
    }
    
    var response = new HttpResponseMessage()
    {
        Content = new ByteArrayContent(outputStream.ToArray()),
        StatusCode = HttpStatusCode.OK,
    };
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

 

Now I go into Postman and POST an image to my new Azure Function endpoint. Here I uploaded a flattering picture of me and unflattering picture of The Oatmeal. He's pretty in real life just NOT HERE. ;)

Image Recognition with Azure Functions

So in just about 15 min with no idea and armed with just my browser, Postman (also my browser), Google/StackOverflow, and Azure Functions I've got a backend proof of concept.

Azure Functions supports Node.js, C#, F#, Python, PHP *and* Batch, Bash, and PowerShell, which really opens it up to basically anyone. You can use them for anything when you just want a function (or more) out there on the web. Send stuff to Slack, automate your house, update GitHub issues, act as a Webhook, etc. There's some great 3d party Azure Functions sample code in this GitHub repo as well. Inputs can be from basically anywhere and outputs can be basically anywhere. If those anywheres are also cloud services like Tables or Storage, you've got a "serverless backed" that is easy to scale.

I'm still learning, but I can see when I'd want a VM (total control) vs a Web App (near total control) vs a "Serverless" Azure Function (less control but I didn't need it anyway, just wanted a function in the cloud.)


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

What is Serverless Computing? Exploring Azure Functions

There’s a lot of confusing terms in the Cloud space. And that’s not counting the term “Cloud.” 😉

  • IaaS (Infrastructure as a Services) – Virtual Machines and stuff on demand.
  • PaaS (Platform as a Service) – You deploy your apps but try not to think about the Virtual Machines underneath. They exist, but we pretend they don’t until forced.
  • SaaS (Software as a Service) – Stuff like Office 365 and Gmail. You pay a subscription and you get email/whatever as a service. It Just Works.

“Serverless Computing” doesn’t really mean there’s no server. Serverless means there’s no server you need to worry about. That might sound like PaaS, but it’s higher level that than.

Serverless Computing is like this – Your code, a slider bar, and your credit card. You just have your function out there and it will scale as long as you can pay for it. It’s as close to “cloudy” as The Cloud can get.

Serverless Computing is like this. Your code, a slider bar, and your credit card.

With Platform as a Service, you might made a Node or C# app, check it into Git, deploy it to a Web Site/Application, and then you’ve got an endpoint. You might scale it up (get more CPU/Memory/Disk) or out (have 1, 2, n instances of the Web App) but it’s not seamless. It’s totally cool, to be clear, but you’re always aware of the servers.

New cloud systems like Amazon Lambda and Azure Functions have you upload some code and it’s running seconds later. You can have continuous jobs, functions that run on a triggered event, or make Web APIs or Webhooks that are just a function with a URL.

I’m going to see how quickly I can make a Web API with Serverless Computing.

I’ll go to http://functions.azure.com and make a new function. If you don’t have an account you can sign up free.

Getting started with Azure Functions

You can make a function in JavaScript or C#.

Getting started with Azure Functions - Create This Function

Once you’re into the Azure Function Editor, click “New Function” and you’ve got dozens of templates and code examples for things like:

  • Find a face in an image and store the rectangle of where the face is.
  • Run a function and comment on a GitHub issue when a GitHub webhook is triggered
  • Update a storage blob when an HTTP Request comes in
  • Load entities from a database or storage table

I figured I’d change the first example. It is a trigger that sees an image in storage, calls a cognitive services API to get the location of the face, then stores the data. I wanted to change it to:

  • Take an image as input from an HTTP Post
  • Draw a rectangle around the face
  • Return the new image

You can do this work from Git/GitHub but for easy stuff I’m literally doing it all in the browser. Here’s what it looks like.

Azure Functions can be done in the browser

I code and iterate and save and fail fast, fail often. Here’s the starter code I based it on. Remember, that this is a starter function that runs on a triggered event, so note its Run()…I’m going to change this.

#r "Microsoft.WindowsAzure.Storage"
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.IO; 
public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    
    string result = await CallVisionAPI(image); //STREAM
    log.Info(result); 
    if (String.IsNullOrEmpty(result))
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    foreach (Face face in imageData.Faces)
    {
        var faceRectangle = face.FaceRectangle;
        faceRectangle.RowKey = Guid.NewGuid().ToString();
        faceRectangle.PartitionKey = "Functions";
        faceRectangle.ImageFile = name + ".jpg";
        await outTable.AddAsync(faceRectangle); 
    }
    return req.CreateResponse(HttpStatusCode.OK, "Nice Job");  
}
static async Task<string> CallVisionAPI(Stream image)
{
    using (var client = new HttpClient())
    {
        var content = new StreamContent(image);
        var url = "https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures=Faces";
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));
        content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        var httpResponse = await client.PostAsync(url, content);
        if (httpResponse.StatusCode == HttpStatusCode.OK){
            return await httpResponse.Content.ReadAsStringAsync();
        }
    }
    return null;
}
public class ImageData {
    public List<Face> Faces { get; set; }
}
public class Face {
    public int Age { get; set; }
    public string Gender { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
}
public class FaceRectangle : TableEntity {
    public string ImageFile { get; set; }
    public int Left { get; set; }
    public int Top { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

GOAL: I’ll change this Run() and make this listen for an HTTP request that contains an image, read the image that’s POSTed in (ya, I know, no validation), draw rectangle around detected faces, then return a new image.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) {
var image = await req.Content.ReadAsStreamAsync();

As for the body of this function, I’m 20% sure I’m using too many MemoryStreams but they are getting disposed so take this code as a initial proof of concept. However, I DO need at least the two I have. Regardless, happy to chat with those who know more, but it’s more subtle than even I thought. That said, basically call out to the API, get back some face data that looks like this:

2016-08-26T23:59:26.741 {"requestId":"8be222ff-98cc-4019-8038-c22eeffa63ed","metadata":{"width":2808,"height":1872,"format":"Jpeg"},"faces":[{"age":41,"gender":"Male","faceRectangle":{"left":1059,"top":671,"width":466,"height":466}},{"age":41,"gender":"Male","faceRectangle":{"left":1916,"top":702,"width":448,"height":448}}]}

Then take that data and DRAW a Rectangle over the faces detected.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    MemoryStream mem = new MemoryStream();
    image.CopyTo(mem); //make a copy since one gets destroy in the other API. Lame, I know.
    image.Position = 0;
    mem.Position = 0;
    
    string result = await CallVisionAPI(image); 
    log.Info(result); 
    if (String.IsNullOrEmpty(result)) {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    MemoryStream outputStream = new MemoryStream();
    using(Image maybeFace = Image.FromStream(mem, true))
    {
        using (Graphics g = Graphics.FromImage(maybeFace))
        {
            Pen yellowPen = new Pen(Color.Yellow, 4);
            foreach (Face face in imageData.Faces)
            {
                var faceRectangle = face.FaceRectangle;
                g.DrawRectangle(yellowPen, 
                    faceRectangle.Left, faceRectangle.Top, 
                    faceRectangle.Width, faceRectangle.Height);
            }
        }
        maybeFace.Save(outputStream, ImageFormat.Jpeg);
    }
    
    var response = new HttpResponseMessage()
    {
        Content = new ByteArrayContent(outputStream.ToArray()),
        StatusCode = HttpStatusCode.OK,
    };
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

 

Now I go into Postman and POST an image to my new Azure Function endpoint. Here I uploaded a flattering picture of me and unflattering picture of The Oatmeal. He’s pretty in real life just NOT HERE. 😉

Image Recognition with Azure Functions

So in just about 15 min with no idea and armed with just my browser, Postman (also my browser), Google/StackOverflow, and Azure Functions I’ve got a backend proof of concept.

Azure Functions supports Node.js, C#, F#, Python, PHP *and* Batch, Bash, and PowerShell, which really opens it up to basically anyone. You can use them for anything when you just want a function (or more) out there on the web. Send stuff to Slack, automate your house, update GitHub issues, act as a Webhook, etc. There’s some great 3d party Azure Functions sample code in this GitHub repo as well. Inputs can be from basically anywhere and outputs can be basically anywhere. If those anywheres are also cloud services like Tables or Storage, you’ve got a “serverless backed” that is easy to scale.

I’m still learning, but I can see when I’d want a VM (total control) vs a Web App (near total control) vs a “Serverless” Azure Function (less control but I didn’t need it anyway, just wanted a function in the cloud.)


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

There's a lot of confusing terms in the Cloud space. And that's not counting the term "Cloud." ;)

  • IaaS (Infrastructure as a Services) - Virtual Machines and stuff on demand.
  • PaaS (Platform as a Service) - You deploy your apps but try not to think about the Virtual Machines underneath. They exist, but we pretend they don't until forced.
  • SaaS (Software as a Service) - Stuff like Office 365 and Gmail. You pay a subscription and you get email/whatever as a service. It Just Works.

"Serverless Computing" doesn't really mean there's no server. Serverless means there's no server you need to worry about. That might sound like PaaS, but it's higher level that than.

Serverless Computing is like this - Your code, a slider bar, and your credit card. You just have your function out there and it will scale as long as you can pay for it. It's as close to "cloudy" as The Cloud can get.

Serverless Computing is like this. Your code, a slider bar, and your credit card.

With Platform as a Service, you might made a Node or C# app, check it into Git, deploy it to a Web Site/Application, and then you've got an endpoint. You might scale it up (get more CPU/Memory/Disk) or out (have 1, 2, n instances of the Web App) but it's not seamless. It's totally cool, to be clear, but you're always aware of the servers.

New cloud systems like Amazon Lambda and Azure Functions have you upload some code and it's running seconds later. You can have continuous jobs, functions that run on a triggered event, or make Web APIs or Webhooks that are just a function with a URL.

I'm going to see how quickly I can make a Web API with Serverless Computing.

I'll go to http://functions.azure.com and make a new function. If you don't have an account you can sign up free.

Getting started with Azure Functions

You can make a function in JavaScript or C#.

Getting started with Azure Functions - Create This Function

Once you're into the Azure Function Editor, click "New Function" and you've got dozens of templates and code examples for things like:

  • Find a face in an image and store the rectangle of where the face is.
  • Run a function and comment on a GitHub issue when a GitHub webhook is triggered
  • Update a storage blob when an HTTP Request comes in
  • Load entities from a database or storage table

I figured I'd change the first example. It is a trigger that sees an image in storage, calls a cognitive services API to get the location of the face, then stores the data. I wanted to change it to:

  • Take an image as input from an HTTP Post
  • Draw a rectangle around the face
  • Return the new image

You can do this work from Git/GitHub but for easy stuff I'm literally doing it all in the browser. Here's what it looks like.

Azure Functions can be done in the browser

I code and iterate and save and fail fast, fail often. Here's the starter code I based it on. Remember, that this is a starter function that runs on a triggered event, so note its Run()...I'm going to change this.

#r "Microsoft.WindowsAzure.Storage"
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using System.IO; 
public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    
    string result = await CallVisionAPI(image); //STREAM
    log.Info(result); 
    if (String.IsNullOrEmpty(result))
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    foreach (Face face in imageData.Faces)
    {
        var faceRectangle = face.FaceRectangle;
        faceRectangle.RowKey = Guid.NewGuid().ToString();
        faceRectangle.PartitionKey = "Functions";
        faceRectangle.ImageFile = name + ".jpg";
        await outTable.AddAsync(faceRectangle); 
    }
    return req.CreateResponse(HttpStatusCode.OK, "Nice Job");  
}
static async Task<string> CallVisionAPI(Stream image)
{
    using (var client = new HttpClient())
    {
        var content = new StreamContent(image);
        var url = "https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures=Faces";
        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));
        content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        var httpResponse = await client.PostAsync(url, content);
        if (httpResponse.StatusCode == HttpStatusCode.OK){
            return await httpResponse.Content.ReadAsStringAsync();
        }
    }
    return null;
}
public class ImageData {
    public List<Face> Faces { get; set; }
}
public class Face {
    public int Age { get; set; }
    public string Gender { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
}
public class FaceRectangle : TableEntity {
    public string ImageFile { get; set; }
    public int Left { get; set; }
    public int Top { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

GOAL: I'll change this Run() and make this listen for an HTTP request that contains an image, read the image that's POSTed in (ya, I know, no validation), draw rectangle around detected faces, then return a new image.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) {

var image = await req.Content.ReadAsStreamAsync();

As for the body of this function, I'm 20% sure I'm using too many MemoryStreams but they are getting disposed so take this code as a initial proof of concept. However, I DO need at least the two I have. Regardless, happy to chat with those who know more, but it's more subtle than even I thought. That said, basically call out to the API, get back some face data that looks like this:

2016-08-26T23:59:26.741 {"requestId":"8be222ff-98cc-4019-8038-c22eeffa63ed","metadata":{"width":2808,"height":1872,"format":"Jpeg"},"faces":[{"age":41,"gender":"Male","faceRectangle":{"left":1059,"top":671,"width":466,"height":466}},{"age":41,"gender":"Male","faceRectangle":{"left":1916,"top":702,"width":448,"height":448}}]}

Then take that data and DRAW a Rectangle over the faces detected.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var image = await req.Content.ReadAsStreamAsync();
    MemoryStream mem = new MemoryStream();
    image.CopyTo(mem); //make a copy since one gets destroy in the other API. Lame, I know.
    image.Position = 0;
    mem.Position = 0;
    
    string result = await CallVisionAPI(image); 
    log.Info(result); 
    if (String.IsNullOrEmpty(result)) {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }
    
    ImageData imageData = JsonConvert.DeserializeObject<ImageData>(result);
    MemoryStream outputStream = new MemoryStream();
    using(Image maybeFace = Image.FromStream(mem, true))
    {
        using (Graphics g = Graphics.FromImage(maybeFace))
        {
            Pen yellowPen = new Pen(Color.Yellow, 4);
            foreach (Face face in imageData.Faces)
            {
                var faceRectangle = face.FaceRectangle;
                g.DrawRectangle(yellowPen, 
                    faceRectangle.Left, faceRectangle.Top, 
                    faceRectangle.Width, faceRectangle.Height);
            }
        }
        maybeFace.Save(outputStream, ImageFormat.Jpeg);
    }
    
    var response = new HttpResponseMessage()
    {
        Content = new ByteArrayContent(outputStream.ToArray()),
        StatusCode = HttpStatusCode.OK,
    };
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
    return response;
}

 

Now I go into Postman and POST an image to my new Azure Function endpoint. Here I uploaded a flattering picture of me and unflattering picture of The Oatmeal. He's pretty in real life just NOT HERE. ;)

Image Recognition with Azure Functions

So in just about 15 min with no idea and armed with just my browser, Postman (also my browser), Google/StackOverflow, and Azure Functions I've got a backend proof of concept.

Azure Functions supports Node.js, C#, F#, Python, PHP *and* Batch, Bash, and PowerShell, which really opens it up to basically anyone. You can use them for anything when you just want a function (or more) out there on the web. Send stuff to Slack, automate your house, update GitHub issues, act as a Webhook, etc. There's some great 3d party Azure Functions sample code in this GitHub repo as well. Inputs can be from basically anywhere and outputs can be basically anywhere. If those anywheres are also cloud services like Tables or Storage, you've got a "serverless backed" that is easy to scale.

I'm still learning, but I can see when I'd want a VM (total control) vs a Web App (near total control) vs a "Serverless" Azure Function (less control but I didn't need it anyway, just wanted a function in the cloud.)


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

How to Add Web Push Notification to Your WordPress Site

Have you noticed the web push notifications used on popular websites like Facebook? Recently one of our readers asked if it was possible to add web push notifications in WordPress. Ofcourse, it is. In this article, we will show you how to add web push… Read More »

The post How to Add Web Push Notification to Your WordPress Site appeared first on WPBeginner.

Have you noticed the web push notifications used on popular websites like Facebook? Recently one of our readers asked if it was possible to add web push notifications in WordPress. Ofcourse, it is. In this article, we will show you how to add web push notification to your WordPress site.

Adding web push notifications to a WordPress site

Why Add Web Push Notifications to Your WordPress Site?

Web push notifications are clickable messages displayed on top of user’s Desktop. They can be shown even when user’s browser is not open.

Web push notifications displayed on Desktop with Google Chrome, Firefox, and Safari web browsers

Aside from desktop, Web push notifications also work on mobile browsers.

Popular sites including Facebook, Pinterest, LinkedIn, and many others are already using web push notifications. It is proving to be more engaging than SMS, email marketing, and other social media. According to a survey, push notifications have a 50% open rate on mobile devices.

This means more engaged audience for your WordPress site and significant boost in your overall page views and returning visitors.

Having said that, let’s take a look at how to add web push notifications to a WordPress site.

Setting up Web Push Notifications in WordPress with OneSignal

OneSignal is a free service that allows you to add push notifications to any website, web, or mobile apps.

First thing you need to do is install and activate the OneSignal plugin. For more details, see our step by step guide on how to install a WordPress plugin.

Upon activation, the plugin will add a new menu item labeled OneSignal in your WordPress admin bar. Clicking on it will take you to plugin’s settings page.

OneSignal WordPress plugin settings

The settings page is divided into Setup and Configuration tabs. The setup tab is actually detailed documentation on how to setup OneSignal push notifications in WordPress. It has the same steps that we will show you in this tutorial.

To setup OneSignal, you will need to add different API keys and application IDs into the plugin settings.

Let’s get started.

Step 1: Create Google Keys

First you need to visit Google Services Wizard website.

Creating Google services app

Simply provide a name for your app and add an Android package name. OneSignal does not use Android package name, but it is a required field.

Next, choose your country and region, then click on the ‘Choose and configure services’ button.

This will bring you to the next screen where you will be asked to select Google services you want to use with your app. You need to click on ‘Enable Google Cloud Messaging’ button.

Enable cloud messaging

You will now see your server API key and Sender ID.

Server API and Sender ID

You need to copy your Sender ID and paste it in WordPress plugin’s Configuration tab under Google Project Number field.

You also need to copy your Server API key and paste it in a text file on your computer. You will need this API key later in this tutorial.

Step 2: Setting up Chrome and Firefox Push Notifications

We will now setup push notifications on Chrome and Firefox. First you need to visit OneSignal website and create your free account.

Once you have created your account, you need to login and click on ‘Add a new app’ button.

Add new OneSignal app

You will be asked to enter a name for your app. You can use any name you want and then click on ‘Create’ button to continue.

App name

On the next page, you will be asked to select a platform to configure. You need to select ‘Website Push’ and then click on the next button to continue.

Website Push

After which you will be asked to select browser platform. You will see Google Chrome and Mozilla Firefox in one box and Safari in another box.

You need to click on Google Chrome and Mozilla Firefox box. We will show you how to setup Safari, later in this article.

Select browser platform

Click on the next button to continue.

In the next step, you will be asked to enter your WordPress site url, Google Server API key, and URL for your default notification icon image.

App settings

If your website does not support SSL/HTTPS, then you need to check the box next to ‘My site is not fully HTTPS’ option. You can also setup SSL on your website if you like, but it’s not required.

Google Chrome does not support web push notifications for non-ssl or http websites. OneSignal solves this problem by subscribing users to a subdomain on their own https domain.

Checking ‘My site is not fully HTTPS’ option will display HTTP fallback options. You will need to choose a subdomain for your app and enter Google Project Number or Sender ID you generated in the first step.

http fallback options

Click on the Save button to continue. Now you can exit this dialog box. You will be prompted with a notice that your setup isn’t complete yet and can be resumed later. Click Yes to close the dialog box.

Step 3: Getting OneSignal Keys

You now need to get OneSignal Keys for your website. From your app dashboard click on App Settings.

App Settings link

This will take you to your app settings page. You need to click on the Keys and IDs tab.

Keys and IDs

This will show your OneSignal App ID and Rest API Key.

App ID and Rest API Key

You need to copy and paste them in OneSignal WordPress plugin’s configuration tab on your site.

Step 4: Setting up Safari Web Push Notifications

Remember we skipped Safari web push notification settings. Now we will show you how to setup Safari web push notifications.

Login to your OneSignal account and go to your App Settings page. Scroll down to web platforms and click on the configure button next to Apple Safari.

Configure Apple Safari

This will bring up a dialog box where you will be asked to enter your site name and site url.

Safari web push notification settings

Then you need to check the box next to ‘I’d like to upload my own notification icons’ option.

You will now see an option to upload different icon sizes. These are square images, use Photoshop or any image editing program to create icons in the exact sizes.

Click on choose file buttons to upload all your icons.

Upload notification icons for Safari web push notification

Click on the Save button and then close the dialog box.

Refresh the App Settings page and scroll down to Web Platforms section. This time you will see ‘Web ID’ under Apple Safari.

Safari web ID

You need to copy this web ID and paste it in Configuration tab of OneSignal plugin on your site.

That’s all, you have successfully setup OneSignal web push notifications for your WordPress site.

Step 5: Testing Web Push Notifications on Your WordPress Site

By default, OneSignal plugin will add a subscription icon to your WordPress site. Visit your website in a supported browser and then click on the subscribe button.

Subscribe push notifications button

You will see the default ‘thank you for subscribing’ message.

Now login to OneSignal account. Click on your app name, and then on App Settings.

Scroll down to the web platforms section and click on the configure button next to Google Chrome and Firefox.

Configure web push notifications for Chrome and Firefox

You will see the platform configuration screen which you filled in earlier. Simply click on Save button and then click on Continue.

testing web push notifications

You will be asked to select target SDK. You need to select WordPress and then click on Next.

Select WordPress

Since you only have one subscriber at the moment your subscriber ID will be automatically filled.

Click on the next button, and you will reach the ‘Test Settings’ step.

Click on ‘Send Test Notification’ button.

Send test notification

One Signal will now send a web push notification.

The notifications appearance may differ depending on which browser you used to subscribe. When the notification appears on your computer screen you need to click on it.

Test notification

It will take you to confirmation screen, showing that you have successfully setup OneSignal web push notifications for your website.

Success message

Return back to the configure screen on OneSignal website and click on ‘Check Notification Status‘ button.

Check notification status

You will now see another success message which indicates that you have successfully added web push notifications to your WordPress site.

How to Send Web Push Notifications in WordPress with OneSignal

The OneSignal web push notifications plugin on your WordPress site will automatically send a notification to all subscribers when you publish a new post.

You can also manually send notifications from your OneSignal App Dashboard. Login to your OneSignal account and click on your app name.

From the menu on your left, click on the ‘New Message’ button.

Sending a new web push notification message

This will bring you to the new message screen. You can enter a title and some content for your notification.

Write your new push notification message in OneSignal

You can also click on the Options, Segment, Schedule/Send Later to further customize your web push notification.

For example, you can link it to a particular page on your site, send it to a particular segment of your users, or schedule it to be sent at a specific time.

We hope this article helped you add web push notification your WordPress site. You may also want to see our list of the best membership plugins for WordPress.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Add Web Push Notification to Your WordPress Site appeared first on WPBeginner.

Basics of Inspect Element: Customizing WordPress for DIY Users

Have you ever wanted to temporarily edit a webpage to see how it would look with specific colors, fonts, styling, etc. It’s possible with a tool that already exists in your browser called Inspect Element. This is a dream come true for all DIY users… Read More »

The post Basics of Inspect Element: Customizing WordPress for DIY Users appeared first on WPBeginner.

Have you ever wanted to temporarily edit a webpage to see how it would look with specific colors, fonts, styling, etc. It’s possible with a tool that already exists in your browser called Inspect Element. This is a dream come true for all DIY users when they find out about it. In this article, we will show you the basics of inspect element and how to use it with your WordPress site.

WordPress beginner's guide to using Inspect tool in Google Chrome

What is Inspect Element or Developer Tools?

Modern web browsers like Google Chrome and Mozilla Firefox has built-in tools which allow web developers to debug errors. These tools show the HTML, CSS, and JavaScript code for a page and how the browser executes the code.

Using Inspect Element tool, you can edit HTML, CSS, or JavaSCript code for any webpage and see your changes live (only on your computer).

For a DIY website owner, these tools can help you preview how a site design would look without actually making the changes for everyone.

For writers, these tools are awesome because you can easily change personal identifying information when taking your screenshots eliminating the need to blur out items altogether.

For support agents, it’s a great way to identify the error that could be causing your galleries to not load or your sliders to not work properly.

We’re just scratching the surface of use-cases. Inspect element is really powerful.

In this article, we will be focusing on Inspect Element in Google Chrome because that’s our browser of choice. Firefox has its own developer tools which can also be invoked by selecting inspect element from browser menu.

Ready? Let’s get started.

Video Tutorial

If you don’t like the video or need more instructions, then continue reading.

Launching Inspect Element and Locating The Code

You can launch inspect element tool by pressing CTRL + Shift + I keys on your keyboard. Alternately you can click anywhere on a web page and select inspect element from browser menu.

Inspect menu

Your browser window will split into two, and the lower window will show the web page’s source code.

The developer tool window is further divided into two windows. On your left, you will see the HTML code for the page. On the right-hand pane, you will see the CSS rules.

HTML and CSS Panes in Inspect window

As you move your mouse over the HTML source you will see the affected area highlighted on the web page. You will also notice CSS rules change to show the CSS for the element you are viewing.

Editing a particular HTML element

You can also take the mouse pointer to an element on the web page, right click and select inspect element. The element you pointed at will be highlighted in the source code.

Editing and Debugging Code in Inspect Element

Both the HTML and CSS in the inspect element window are editable. You can double click anywhere in the HTML source code and edit the code as you like.

Editing HTML code in inspect element tool

You can also double click and edit any attributes and styles in the CSS pane. To add a custom style rule click on the + icon at the top of CSS pane.

Editing CSS in the inspect element tool

As you make changes to the CSS or HTML those changes will be reflected in the browser instantly.

Live CSS changes in the browser screen

Note, that any changes you make here are not saved anywhere. Inspect element is a debugging tool, and it does not write your changes back to the files on your server. This means that if you refresh the page, all your changes will be gone.

To actually make the changes, you will have to edit your WordPress theme’s stylesheet or relevant template to add the changes you want to save.

Before you start editing your existing WordPress theme using Inspect Element tool, make sure you that you save all your changes by creating a child theme.

Easily Find Errors On Your Site

Inspect element has an area called Console which shows all the errors that exist on your website. When trying to debug an error or requesting support from plugin authors, it’s always helpful to look here to see what the errors are.

Browser Console Error

For example, if you were an OptinMonster customer wondering why your optin is not loading, then you can easily find the problem “your page slug does not match”.

If your sharebar wasn’t working properly, then you can see that there’s a JavaScript error.

Tools like the Inspect Element Console and SupportAlly help you get better customer support because the technical support team love customers who take initiative in providing detailed feedback of the issue.

We hope this article helped you learn the basics of inspect element and how to use it with your WordPres site. You may also want to take a look at the default WordPress generated CSS cheat sheet to speed up your theme development skills.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Google+.

The post Basics of Inspect Element: Customizing WordPress for DIY Users appeared first on WPBeginner.

Can Software Make You Less Racist?

I don’t think we computer geeks appreciate how profoundly the rise of the smartphone, and Facebook, has changed the Internet audience. It’s something that really only happened in the last five years, as smartphones and data plans dropped radically in price and became accessible – and addictive – to huge

I don't think we computer geeks appreciate how profoundly the rise of the smartphone, and Facebook, has changed the Internet audience. It's something that really only happened in the last five years, as smartphones and data plans dropped radically in price and became accessible – and addictive – to huge segments of the population.

People may have regularly used computers in 2007, sure, but that is a very different thing than having your computer in your pocket, 24/7, with you every step of every day, integrated into your life. As Jerry Seinfeld noted in 2014:

But I know you got your phone. Everybody here's got their phone. There's not one person here who doesn't have it. You better have it … you gotta have it. Because there is no safety, there is no comfort, there is no security for you in this life any more … unless when you're walking down the street you can feel a hard rectangle in your pants.

It's an addiction that is new to millions – but eerily familiar to us.

The good news is that, at this moment, every human being is far more connected to their fellow humans than any human has ever been in the entirety of recorded history.

Spoiler alert: that's also the bad news.

Nextdoor is a Facebook-alike focused on specific neighborhoods. The idea is that you and everyone else on your block would join, and you can privately discuss local events, block parties, and generally hang out like neighbors do. It's a good idea, and my wife started using it a fair amount in the last few years. We feel more connected to our neighbors. But one unfortunate thing you'll find out when using Nextdoor is that your neighbors are probably a little bit racist.

I don't use Nextdoor myself, but I remember Betsy specifically complaining about the casual racism she saw there, and I've also seen it mentioned several times on Twitter by people I follow. They're not the only ones. It became so epidemic that Nextdoor got a reputation for being a racial profiling hub. Which is … not good.

Social networking historically trends young, with the early adopters. Facebook launched as a site for college students. But as those networks grow, they inevitably age. They begin to include older people. And those older people will, statistically speaking, be more racist. I apologize if this sounds ageist, but let me ask you something: do you consider your parents a little racist? I will personally admit that one of my parents is definitely someone I would label a little bit racist. It's … not awesome.

The older the person, the more likely they are to have these "old fashioned" notions that the presence of black people on your block is inherently suspicious, and marriage should probably be defined as between a man and a woman.

In one meta-analysis by Jeffrey Lax and Justin Phillips of Columbia University, a majority of 18–29 year old Americans in 38 states support same sex marriage while in only 6 states do less than 45% of 18–29 year olds support same-sex marriage. At the same time not a single state shows support for same-sex marriage greater than 35% amongst those 64 and older

The idea that regressive social opinions correlate with age isn't an opinion; it's a statistical fact.

Support for same-sex marriage in the U.S.

18 - 29 years old    65%
30 - 49 years old    54%
50 - 64 years old    45%
65+ years old        39%

Are there progressive septuagenarians? Sure there are. But not many.

To me, failure to support same-sex marriage is as inconceivable as failing to support interracial marriage. Which was not that long ago, to the tune of the late 60s and early 70s. If you want some truly hair-raising reading, try Loving v. Virginia on for size. Because Virginia is for lovers. Just not those kind of lovers, 49 years ago. In the interests of full disclosure, I am 45 years old, and I graduated from the University of Virginia.

You're more connected with your neighbors than ever before. But through that connection you may also find out some regressive things about your neighbors that you'd never have discovered in years of the traditional daily routine of polite waves, hellos from the driveway, and casual sidewalk conversations.

To their immense credit, rather than accepting this status quo, Nextdoor did what any self-respecting computer geek would do: they changed their software. Now, when you attempt to post about a crime or suspicious behavior …

… you get smart, just in time nudges to think less about race, and more about behavior.

The results were striking:

Nextdoor claims this new multi-step system has, so far, reduced instances of racial profiling by 75%. It’s also decreased considerably the number of notes about crime and safety. During testing, the number of crime and safety issue reports abandoned before being published rose by 50%. “It’s a fairly significant dropoff,” said Tolia, “but we believe that, for Nextdoor, quality is more important than quantity.”

I'm a huge fan of designing software to help nudge people, at exactly the right time, to be their better selves. And this is a textbook example of doing it right.

Would using Nextdoor and encountering these dialogs make my aforementioned parent a little bit less racist? Probably not. But I like to think they would make that parent stop for at least a moment and consider the importance of focusing on the behavior that is problematic, rather than the individual person. This is a philosophy I promoted on Stack Overflow, I continue to promote with Discourse, and I reinforce daily with our three kids. You never, ever judge someone by what they look like. Look at what they do.

If you were getting excited about the prospect of validating Betteridge's Law yet again, I'm sorry to disappoint you. I truly do believe software, properly designed software, can not only help people be more civil to each other, but can also help people – maybe even people you love – behave a bit less like racists online.

[advertisement] At Stack Overflow, we help developers learn, share, and grow. Whether you’re looking for your next dream job or looking to build out your team, we've got your back.

Sucuri vs CloudFlare (Pros and Cons) – Which One is Better?

Due to an increased emphasis on website security in today’s digital landscape, one of the most common requests we’ve gotten from readers is to do a pros and cons analysis of Sucuri vs CloudFlare to explain which one is better. Sucuri and CloudFlare are online… Read More »

The post Sucuri vs CloudFlare (Pros and Cons) – Which One is Better? appeared first on WPBeginner.

Due to an increased emphasis on website security in today’s digital landscape, one of the most common requests we’ve gotten from readers is to do a pros and cons analysis of Sucuri vs CloudFlare to explain which one is better. Sucuri and CloudFlare are online services that offer website firewall, CDN, and DDoS protection services. In this article, we will compare Sucuri vs Cloudflare with pros and cons to find out which one is better.

Sucuri vs CloudFlare (Pros and Cons)

Even the most secure websites on the internet are vulnerable to distributed denial of service attacks (DDoS), hacking attempts, and malware injection.

As a WordPress site owner you can use some security best practices like password protecting admin directory, limiting login attempts, adding two factor authentication, etc.

However these tips only work on software level which leaves your website mostly open to other types of attacks. These attacks can cause financial damage, data loss, poor search rankings and bad user experience.

Sucuri and CloudFlare offer a website application firewall (WAF).

This means that all your website’s traffic goes through their server scanners. If a request looks malicious, then the firewall would block it before it even reaches your website.

On the surface, these two services look nearly identical, but there are some key differences.

In this comparison, we’ll focus on:

  • Features
  • Pricing
  • Malware Removal Service

By the end, you’ll know exactly which platform is best for you.

Ready? Let’s compare Sucuri vs Cloudflare.

Features

In this section, we will look at the features offered by Sucuri and CloudFlare.

It’s important to note that both services offer different plans that come with different set of features.

As a user, make sure you’re not a victim of their marketing site because not all plans come with all the features.

CloudFlare Features

CloudFlare is best known for their free CDN service. They specialize in mitigating DDOS attacks using their Website Application Firewall product. CloudFlare keep your site available to users during an attack or under heavy traffic when your server is not responsive.

Their website firewall blocks suspicious traffic before it even reaches your website. The firewall also extends to form submissions which protects your website from comment spam and registration spam.

CloudFlare website firewall

CloudFlare also offers free and custom SSL certificates with all their plans. Free and pro plans only allow you to use CloudFlare issued certificate. For custom certificate you will need to upgrade to their Business or Enterprise plan.

While CloudFlare offer a free option that includes CDN, most other features including their Website Application Firewall require a paid plan.

CloudFlare doesn’t offer server scanning service to detect malware. It also doesn’t offer a malware removal guarantee if you were to be hacked on their watch.

Sucuri Features

Sucuri is one of the most reputable website security and monitoring service. They offer comprehensive website monitoring, scanning for malware, DDoS protection, and malware removal services.

Sucuri offers CloudProxy, a website firewall and load balancing service. It blocks suspicious traffic from reaching your website by effectively blocking DDoS attacks, code injection, bad bots, and other website threats. See our case study of how Sucuri helped us block 450,000 attacks in 3 months.

Sucuri offers integration with the free Let’s Encrypt SSL for their basic plan. You can also use custom SSL certificates with their professional and business plans.

Sucuri CloudProxy

Sucuri scans your website regularly for file changes, code injection, and malware. They clean up hacked sites, with support for all popular CMS software like WordPress, Joomla, Drupal, etc.

Winner: Sucuri is a clear winner because they offer a better combination of tools and services (Website Firewall + Load Balancing + Malware Cleanup / Hack Repair).

Pricing

Pricing is an important factor for many small businesses.

Here, we will compare the different pricing plans offered by CloudFlare and Sucuri, so you know exactly what you’re getting for your money.

FREE is not always better :)

CloudFlare Pricing Plans

CloudFlare offers a free CDN service for all. They don’t charge you for the bandwidth which means you will be able to use their free CDN regardless of your traffic volume.

However, this free plan does not come with the website application firewall. Your website may benefit from CDN, but it will not be properly protected against DDoS attacks, spam, bad traffic, etc.

For their web application firewall, you need the Pro plan which costs $20 / month (this is what you need for improved security).

This pro plan does not include advanced DDoS mitigation and custom SSL. For those features, you will need their Business plan which costs $200 per month.

Sucuri Pricing Plans

Unlike CloudFlare, Sucuri doesn’t offer a free plan. Their website security stack plan starts at $199.99 for an year, which is cheaper than CloudFlare’s pro plan.

This basic plan includes full website monitoring, website application firewall, DDoS protection, malware removal, and free LetsEncrypt SSL certificate.

Instead of excluding features from lower level plans, Sucuri uses priority as an incentive for their higher paying plans.

For example, malware removal estimated time for basic plan is 12 hours, 6 hours for professional plan, and 4 hours for business plan. However, the actual cleanup timings are way faster than that for all customers.

They offer 24/7 support as part of all plans. Their business plan subscribers can also use the Live Chat support.

Winner: Sucuri is an obvious choice for small businesses when it comes to pricing. CloudFlare Pro costs $240 / year vs Sucuri cost $199 / year and offer more features. To unlock same features, you’d have move up to CloudFlare’s $2400 / year plan. Sucuri’s most expensive plan is at $499 / year.

Malware Removal Service

Apart from denial of service attacks, malware and code injections are the most common threats faced by WordPress site owners.

Let’s see how both services protect your website against those common threats.

Website security and malware removal

CloudFlare – Security and Malware Removal

CloudFlare free version is basically a content delivery network which helps make your website fast.

The website security firewall comes with their paid plan. It includes CloudFlare’s ready to use custom rules set. These rules protect your site from common code injection hacks, XSS JavaScript exploits, and form submissions.

However, they do not offer file change detection, malware scanning, blacklist monitoring, and many other security features. You can add third-party apps for malware scanning, but these services will cost you additional fees.

Sucuri – Security and Malware Removal

Sucuri is a security focused company. They specialize in monitoring websites and protecting them against malware and other attacks.

Sucuri’s website application firewall protects you against DDOS, SQL injections, XSS JavaScript injections, comment and contact form spam.

However, if something crosses all those security barriers and somehow reaches your website, then Sucuri offers to clean up your website (for free).

If you already have a website affected with malware, then Sucuri will clean that up as well.

Winner: Sucuri – For combining website application firewall with monitoring, malware protection, and clean up services.

Conclusion

CloudFlare and Sucuri both offer protection against DDoS attacks on your website. CloudFlare does a little better in the content delivery network area.

Sucuri fares better in the overall features, better security monitoring, and lower prices. If you are using a CMS like WordPress, then Sucuri is what you need.

We hope this article helped you compare pros and cons of Sucuri vs CloudFlare. You may also want to see our list of 7 best WordPress backup plugins.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post Sucuri vs CloudFlare (Pros and Cons) – Which One is Better? appeared first on WPBeginner.