7-amazing-wordpress-data-visualization-plugins

7 Amazing WordPress Data Visualization Plugins that Professionals use 1

It is a fact that people are visual, which means that media content is more effective than written content.

As a result, the experts and developers behind WordPress have developed various ways of creating visual representations when editing websites.

Data visualization in WP is the act of presenting different types of data visually. Website creators have used these techniques for many years, but they keep getting better over time.

Reasons to Use Data Visualization

#1 Easy interpretation

Another great reason for creating these visual techniques is to make it easy for readers to understand the data.

Graphs, charts, and art are easier to understand than text.

#2 Convenient interaction with data

When website experts visualize data in WordPress, the main aim is to make it easy for them to understand the data they are about to present.

Even dealing with past data and relating it to the current data is still easy. So, the experts also get to benefit from these techniques.

#3 Fancy visuals

Apart from graphs and other basic representations, the use of art, illustrations, images, and videos is more appealing to viewers.

Research has shown that people will be glued to WP websites with striking visual representations to a greater degree than those bearing only art.

#4 Customizable data

Most WordPress websites have an agenda, which might be to market a certain brand or convey specific information.

In this case, unique and customized data is necessary to make you authentic.

Data visualization allows a person to change the form of data with ease.

Currently, the plugins that are used make it possible to edit data at any time, which means that you can update it in the future.

#5 Helps in decision making

Decision-makers are best guided by factual data as it appears in various representations.

Researchers and website owners rely on the results from charts, graphs and other visual data in WP.

How Data Is Visualized in WordPress

When web designers and experts are tasked with creating content using data visualization, what comes to mind is the use of particular methods.

The good thing is that they have many options.

When any of them is used in the right way, the results are not only amazing but easy to interpret and fun to interact with.

Here are some common ideas for visualizing data.

#1 Charts and graphs

This is a basic idea for visualizing data.

Line charts, pie charts, and bar graphs are common examples used.

Graphs and Charts - Data Visualization

Various plugins, as we are going to see later, allow us to create these charts and graphs.

Experts find them very simple to use while users understand them very quickly.

Bar graphs compare different groups of data, but they also present data change over time.

Line graphs simply present the change of data over a large period. The good thing is that they can show these changes for two or more groups.

Lastly, the pie chart compares different groups of data with a whole.

#2 Timeline with event graphs

These are almost like graphs that we have discussed above, but they are more complex.

Timeline Chart - WordPress Data Visualization

They tend to compare events that have occurred over time. Therefore, they combine a line graph with area graphs.

They are detailed in that they will mark the events that brought about the changes indicated on the graph.

WordPress websites meant to present research data heavily rely on the timeline along with event graphs.

For the readers and end-users, interpreting the data will require a second look to get it right.

However, a good presentation that marks and explains the events makes it all clear and easy to comprehend.

#3 Data tables

They are also called comparison tables, and they include the use of different columns to show various types of data.

Pricing Table - Data Tables - data visualization

The rows show the considered factor of analysis, and users can easily follow this.

Data from comparison tables can be extracted to create line graphs for further clarification and easy interpretation.

#4 Maps

Most of us might have interacted with maps. Today, they are popularly added to WP websites to show directions.

Maps - Data Visualization

Initially, maps were added to present some data like the distribution of people, resources and much more.

Today, they are still used for such purposes.

Maps can also have figures displayed in each geographical location, or they can be shaded with different colors with a key to explain what each color means.

Maps are fun and easy to interact with for both the experts and users.

#5 Pictorial and video presentations

Simple pictures were initially used in WordPress, but as things get more sophisticated, the use of actual images is becoming very popular.

They are more appealing and colorful to the users and also add more value to the users.

Pictures and Videos for your WordPress website

The use of videos with data is also especially popular.

The good thing about the video is that you can present any data and explain it using all the above methods that we have discussed.

The ActiveWizards experts are good at presenting data in a way that is easy for you and the users at large.

Best WordPress Data Visualization Plugins

Now that you know the basic styles and ways of presenting data in WP, it is time to look at the common plugins and tools used by experts to create these presentations.

We will examine seven of the best and explain how they work.

#1. WordPress Graphs & Charts

WordPress Graphs & Charts - Best WordPress Data Visualization Plugin

View Demo More Info & Download

It is readily available to make interactive, appealing, statistical and versatile graphs and pie charts.

They make use of both HTML5 and SVG in combination.

With such power, your visualization will enjoy the latest browser and graphics technology.

#2 wpDataTables

wpDataTables - Best WordPress Data Visualization Plugin

View Demo More Info & Download

This is a more detailed plugin that provides various visual representations like comparison tables, charts, and graphs.

The good thing is that it allows you to import Excel and Google document tables.

If you have the administrative rights, you can just edit the data from either the back end or the front end of the WP page.

When it comes to the security of the data, the plugin has a security layer where you can regulate the use of data.

#3 Snowball

Snowball - Best WordPress Data Visualization Plugin

View Demo More Info & Download

If your wish is to deliver well-articulated data as a blogger or web content writer, this is the option to choose.

If you have already interacted with it, you will agree that it is not just a visual representation plugin as it offers more.

The UI provides blocks that can be customized to suit different styles and tastes. Therefore, it is easy to maintain the authenticity of your WordPress website through customization.

It has more sophisticated graphs like the Choropleth graph and Scatter plots on top of the ordinary charts and line graphs.

#4 WP Google Maps

WP Google Maps - Best WordPress Data Visualization Plugin

View Demo More Info & Download

This is another free plugin that allows experts to add maps meant to give travel directions to users.

Markers are easy to drag and drop even for readers.

If you are trying to present data from research, this plugin will also come in handy.

It is a useful technology that is free of charge.

Therefore, writers and bloggers who want to add value to their websites can easily make use of it.

#5 WP Business Intelligence Lite

WP Business Intelligence Lite - Best WordPress Data Visualization Plugin

View Demo More Info & Download

This last plugin is highly detailed for business people who want to keep their loyal and potential clients updated in real-time.

When connected to the MySQL database, it will show the data in the form of graphs and charts.

There is more to unlock from this plugin, and it is better to have an expert to explore it for you.

Conclusion

Many WordPress website owners and writers now know how data visualization is important to attract new traffic and lock in the loyal users.

With the insights above, all have a better understanding of how to go about enhancing a WordPress website for more benefits.

Note: This guide on the Best WordPress Data Visualization Plugins was contributed by Benard Njuguna. If you have an interesting topic to contribute, then check our Guest Posting Guidelines.

If you love this article, do share it on social media and drop your comment below.

7 Amazing WordPress Data Visualization Plugins that Professionals use - Pinterest Image

For more useful WordPress Plugin Collections,

how-to-delete-your-wordpress-account-or-blog

Difficulty:BeginnerLength:ShortLanguages:

Is it time to say goodbye to your WordPress website?

Maybe it’s time for a fresh start, or perhaps you want to distance yourself from the kind of content you used to create—whatever your reasons, you probably won’t want your abandoned website hanging around on the Internet forever.

In this article, I’ll show you how to permanently delete your WordPress website, regardless of whether you created your site via WordPress.com or WordPress.org. And, if you got carried away and created multiple WordPress.com websites, then I’ll also be showing you how to delete all of these sites simultaneously, by cancelling your WordPress account. 

WordPress.com vs. WordPress.org: What’s the Difference?

The process for deleting your website will differ depending on whether it’s a WordPress.com or a WordPress.org site, so let’s start by clarifying the differences between the two:

  • WordPress.org, sometimes referred to as self-hosted WordPress, is where you download the free WordPress software and install it on your own server. With a WordPress.org website, you’re solely responsible for hosting and maintenance. 
  • WordPress.com takes care of the hosting for you. Rather than downloading and installing the WordPress software, simply head over to WordPress.com, click Get started, complete a few forms, and WordPress.com will create your website for you.  

The Internet Is Forever

In this article, I’ll show you how to delete your website, so it no longer appears at its URL or appears in Google search results. However, if your website has been archived by third parties then there’s a chance your content will still be accessible via these third-party services. 

Deleting your website will make it less accessible, but there’s no guarantee that a determined third party won’t be able to recover some or all of your deleted content. 

How Do I Close My WordPress.com Account?

Are you performing some admin and want to delete all the accounts that you no longer use? Or perhaps you want to delete your existing WordPress account, so you can re-register and start again from scratch? 

When you close your account, WordPress will also delete all the websites associated with that account. If you got carried away and created multiple different websites, then cancelling your account may be easier than deleting each website individually.  

To close your WordPress.com account:

  • Log in to your account, if you haven’t already.
  • Head over to the Account Settings screen.
  • Scroll to the bottom of the screen and select Close your account permanently.
Cancel your WordPress account by navigating to Account Settings and selecting Close your account permanently
  • Review the list of content you’re about to delete, and if you’re happy to proceed then click Close account.
Review the items that will be deleted and if youre happy to proceed click Close account

WordPress will now delete your username, all the sites you own, and all of your content. 

Deleting a WordPress.com Blog From the Dashboard

If you created your website via WordPress.com, then you can delete it directly from the WordPress Dashboard. Note that when you delete your WordPress.com website, you’ll also lose access to your site’s URL unless you purchased the domain. 

To delete your WordPress.com site, first log in to your WordPress account, if you haven’t already.

In the left-hand menu, select Manage > Settings. Now scroll to the very bottom of the screen and select Delete your site permanently.

At this point, you’ll have the option to export all of your posts, pages, and settings as a ZIP file. If you ever change your mind and want to reinstate your website, then you can upload this ZIP file to a new WordPress site and recover your content. This step is optional, but it’s also a one-time offer: if you don’t export now, then your content will be lost forever. If you do want to hang on to a copy of your content, then click Export all. Once the export is complete, click Back to resume deleting your website.

Review all the information about the content you’re about to delete, and if you’re happy to proceed, then click Delete site. When prompted, enter your website’s full URL for a final confirmation. 

This is it! If you’re still determined to permanently remove your website from the World Wide Web, then click the Delete this site button and your WordPress website will be gone forever.  

How to Delete Your Self-Hosted Website With cPanel

If you used cPanel to set up your self-hosted WordPress website, then you can also use cPanel to delete it:  

  • Log in to your cPanel Dashboard.
  • Select the Hosting tab. 
  • Find the website that you want to delete and click its accompanying Switch button.
  • On the subsequent screen, select WordPress
  • Select Uninstall. After a few moments, you should see the following message: Software has been uninstalled.

Your WordPress website has now been deleted.

Delete Your Self-Hosted WordPress Website Manually 

If you installed the WordPress software on your server manually, then you’ll also need to remove it manually. This process can vary depending on whether you have FTP or SFTP access, or you access your web server via a web-based file manager:

1. I have FTP or SFTP Access

If you have FTP or SFTP access, then you can delete your WordPress website using an FTP client:

  • Log in to your FTP server. 
  • Locate your WordPress directory, and either Control-click or right-click it, depending on whether you’re running Windows or macOS. 
  • When prompted, select Delete.

2. I Use a Web-Based File Manager

If you have access to a web-based file manager, then:

  • Log in to your web hosting dashboard.
  • Open your file manager application.
  • Navigate to the WordPress directory that you want to delete, and hit the Delete button. 

Delete Your Website’s Database Using MySQL

After deleting your WordPress website, you may also want to delete your website’s MySQL database. You can remove this database using the following MySQL command: 

$ mysql -h HOST -u USERNAME -p PASSWORD -D wordpress
$ DROP wordpress

Note that you’ll need to replace wordpress with the name of your WordPress database, which is located in your wp-config.php file. The process for locating this database will vary depending upon your hosting provider—for example, if you were using cPanel, then you would typically use the file manager to browse to your WordPress directory, which contains the wp-config.php file.

Delete Your Database Using cPanel

If you’re a cPanel user, then:

  • Log in to your cPanel Dashboard.
  • Scroll to the Databases section, and select MySQL Databases.
  • Select the MySQL database that you want to delete.
  • Find the Delete Database link, and give it a click. 
  • Read the onscreen warning, and if you’re happy to proceed, then click Delete Database.

cPanel will now delete your website’s database. 

Conclusion 

In this quick tip, I showed you how to permanently delete your WordPress.com or WordPress.org website, and how to optionally delete your site’s MySQL database. 

Are you deleting an outdated WordPress website with the intention of starting again from scratch? If you’re creating a brand new WordPress website, then be sure to check out some of our other WordPress tutorials, as they contain all the information you need to create a modern, professional, and engaging WordPress website. 


The Best WordPress Plugins on CodeCanyon

Explore thousands of the best WordPress plugins ever created on CodeCanyon. With a low-cost one time payment, you can purchase these high-quality WordPress plugins and improve your website experience for you and your visitors. 

Here are a few of the best-selling and up-and-coming WordPress plugins available on ThemeForest for 2020.

5-bad-habits-that-can-hurt-your-wordpress-website

When you build a WordPress website, you open yourself up to an entire world of possibilities. That is both a good and bad thing.

The built-in conveniences and ability to extend functionality with just a few clicks make site owners feel at ease. The bright side is that this allows us to do more with a shoestring budget than we may have thought possible. But it can also lull us into a false sense of security.

The result is that we may be putting our websites at risk without fully realizing it. WordPress, after all, is not a set-it-and-forget-it CMS. On the contrary, it requires us to develop good practices and constant vigilance.

Here are five bad habits that, while innocent in intent, can bring unwanted drama to your WordPress install. We’ll cover both what can go wrong and provide simple solutions that will help you avoid future problems.

Leaving Unused Plugins Installed

It’s a pretty common practice. We search through the WordPress Plugin Repository and find something of interest. We install it and plan on seeing what it can do. However, maybe it isn’t a great fit, or maybe we never test it at all. Still, it sits there.

Keeping unused plugins around can be costly. From a security perspective, it can be dangerous. A vulnerable piece of code could very well lead to malware being installed on your server. This could, in turn, do untold amounts of damage to your site.

The unfortunate truth is that not all plugins are well-written or maintained. Some are even abandoned by their authors. If you happen to be the unlucky person who still has one of these plugins installed, you are a target.

Beyond that, the more plugins you have installed, the harder it is to troubleshoot any errors that arise. Clutter only serves to complicate the process.

The Solution

It’s okay to install plugins and test them out (preferably on a staging site). But make a habit of removing unwanted plugins – even those that aren’t currently active on your website. Routinely browse through your WordPress back end to check for items you don’t need.

Vehicles in a junk yard.security plugin and make sure your install is up-to-date. It won’t stop every potential attack, but it can thwart the basic stuff.

A cat sleeping next to a computer.themes available. But there are times when commercial software just makes more sense. It might be a better fit for your needs or offer more powerful functionality. Plus, commercial-grade support is always welcome when it comes to mission-critical tools.

However, these items take often take a sustained financial commitment, as one-time purchases are becoming rare. Much of the commercially-available plugins and themes for WordPress tend to require yearly license renewals.

This recurring cost helps the developer provide support, add new features and fix bugs. It means that the software will continue to be actively developed, which benefits everybody.

Yet, I am still amazed at how often I see websites using software with long-expired licenses. This can be both a security and functionality nightmare. Eventually, something is going to either become vulnerable or break altogether as new versions of WordPress are released.

The Solution

Do some research before you buy a plugin or theme. Determine what the future costs will be and if they are manageable. Just as importantly, inform your clients about these licenses! Quite often, a license will expire simply because a client doesn’t know about it.

Man looking through his wallet.SEO – there are so many options for each. Collect enough of these plugins and eventually, a few are going to patrol the same territory.

The Solution

When possible, choose a definitive path for the functionality you need in any particular category. Either find a plugin that does just about everything you want, or piece together a few niche items.

This is where a plugin with its own ecosystem, such as WooCommerce, makes life easier. Through its many extensions, you can add just the capabilities you really need – thus avoiding overlap.

A pile of clocks.backup plugin. There are also a number of third-party services such as ManageWP, InfiniteWP or even Jetpack that offer similar functionality.

Whichever you choose, be sure to keep a copy of your site somewhere other than your web host. That could be a cloud storage service or even your local machine. That way, you’ll always have access – just in case.

Broken hard drive.maintenance, you can often avoid the most serious kinds of problems.

Not sure you’re up to the challenge? Start off with something simple, like setting a weekly reminder to update your installation. From there, set a monthly reminder that urges you to take inventory of plugins and security.

Follow that plan and, pretty soon, your website will be in tip-top shape.

abstracting-wordpress-code-to-reuse-with-other-cms

About The Author

Leonardo Losoviz is a freelance developer and writer, with an ongoing quest to integrate innovative paradigms (Serverless PHP, server-side components, GraphQL) …
More about
Leonardo

Making our code CMS-agnostic, as much as possible, enables us to easily port our application to another CMS if the need arises. In this article we will learn how to abstract a WordPress application, making its code readily available for other frameworks or CMSs.

In the first part of this series, we learned the key concepts to build an application that is as CMS-agnostic as possible. In this second and final part, we will proceed to abstract a WordPress application, making its code ready to be used with Symfony components, Laravel framework, and October CMS (which is based on Laravel).

Accessing Services

Before we start abstracting the code, we need to provide the layer of dependency injection to the application. As described in the first part of this series, this layer is satisfied through Symfony’s DependencyInjection component. To access the defined services, we create a class ContainerBuilderFactory which simply stores a static instance of the component’s ContainerBuilder object:

use SymfonyComponentDependencyInjectionContainerBuilder;

class ContainerBuilderFactory {
  private static $instance;
  public static function init()
  {
    self::$instance = new ContainerBuilder();
  }
  public static function getInstance()
  {
    return self::$instance;
  }
}

Then, to access a service called "cache", the application requests it like this:

$cacheService = ContainerBuilderFactory::getInstance()->get('cache');
// Do something with the service
// $cacheService->...

Abstracting WordPress Code

We have identified the following pieces of code and concepts from a WordPress application that need be abstracted away from WordPress’s opinionatedness:

  • accessing functions
  • function names
  • function parameters
  • states (and other constant values)
  • CMS helper functions
  • user permissions
  • application options
  • database column names
  • errors
  • hooks
  • routing
  • object properties
  • global state
  • entity models (meta, post types, pages being posts, and taxonomies —tags and categories—)
  • translation
  • media.

Let’s proceed to abstract them, one by one.

Note: For ease of reading, I have omitted adding namespaces to all classes and interfaces throughout this article. However, adding namespaces, as specified in PHP Standards Recommendation PSR-4, is a must! Among other advantages, the application can then benefit from autoloading, and Symfony’s dependency injection can rely on automatic service loading as to reduce its configuration to the bare minimum.

Accessing functions

The mantra “code against interfaces, not implementations” means that all those functions provided by the CMS cannot be accessed directly anymore. Instead, we must access the function from a contract (an interface), on which the CMS function will simply be the implementation. By the end of the abstraction, since no WordPress code will be referenced directly anymore, we can then swap WordPress with a different CMS.

For instance, if our application accesses function get_posts:

$posts = get_posts($args);

We must then abstract this function under some contract:

interface PostAPIInterface
{
  public function getPosts($args);
}

The contract must be implemented for WordPress:

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args) {
    return get_posts($args);
  }
}

A service "posts_api" must be added to the dependency injection services.yaml configuration file, indicating which class resolves the service:

services:
  posts_api:
    class: WPPostAPI

And finally, the application can reference the function through service "posts_api":

$postsAPIService = ContainerBuilderFactory::getInstance()->get('posts_api');
$posts = $postsAPIService->getPosts($args);

Function names

If you have noticed from the code demonstrated above, function get_posts is abstracted as getPosts. There are a couple of reasons why this is a good idea:

  • By calling the function differently, it helps identify which code belongs to WordPress and which code belongs to our abstracted application.
  • Function names must be camelCased to comply with PSR-2, which attempts to define a standard for writing PHP code.

Certain functions can be redefined, making more sense in an abstract context. For instance, WordPress function get_user_by($field, $value) uses parameter $field with values "id", "ID", "slug", "email" or "login" to know how to get the user. Instead of replicating this methodology, we can explicitly define a separate function for each of them:

interface UsersAPIInterface
{
  public function getUserById($value);
  public function getUserByEmail($value);
  public function getUserBySlug($value);
  public function getUserByLogin($value);
}

And these are resolved for WordPress:

class WPUsersAPI implements UsersAPIInterface
{
  public function getUserById($value)
  {
    return get_user_by('id', $value);
  }
  public function getUserByEmail($value)
  {
    return get_user_by('email', $value);
  }
  public function getUserBySlug($value)
  {
    return get_user_by('slug', $value);
  }
  public function getUserByLogin($value)
  {
    return get_user_by('login', $value);
  }
}

Certain other functions should be renamed because their names convey information about their implementation, which may not apply for a different CMS. For instance, WordPress function get_the_author_meta can receive parameter "user_lastname", indicating that the user’s lastname is stored as a “meta” value (which is defined as an additional property for an object, not originally mapped in the database model). However, other CMSs may have a column "lastname" in the user table, so it doesn’t apply as a meta value. (The actual definition of “meta” value is actually inconsistent in WordPress: function get_the_author_meta also accepts value "user_email", even though the email is stored on the user table. Hence, I’d rather stick to my definition of “meta” value, and remove all inconsistencies from the abstracted code.)

Then, our contract will implement the following functions:

interface UsersAPIInterface
{
  public function getUserDisplayName($user_id);
  public function getUserEmail($user_id);
  public function getUserFirstname($user_id);
  public function getUserLastname($user_id);
  ...
}

Which are resolved for WordPress:

class WPUsersAPI implements UsersAPIInterface
{
  public function getUserDisplayName($user_id)
  {
    return get_the_author_meta('display_name', $user_id);
  }
  public function getUserEmail($user_id)
  {
    return get_the_author_meta('user_email', $user_id);
  }
  public function getUserFirstname($user_id)
  {
    return get_the_author_meta('user_firstname', $user_id);
  }
  public function getUserLastname($user_id)
  {
    return get_the_author_meta('user_lastname', $user_id);
  }
  ...
}

Our functions could also be re-defined as to remove the limitations from WordPress. For instance, function update_user_meta($user_id, $meta_key, $meta_value) can receive one meta attribute at a time, which makes sense since each of these is updated on its own database query. However, October CMS maps all meta attributes together on a single database column, so it makes more sense to update all values together on a single database operation. Then, our contract can include an operation updateUserMetaAttributes($user_id, $meta) which can update several meta values at the same time:

interface UserMetaInterface
{
  public function updateUserMetaAttributes($user_id, $meta);
}

Which is resolved for WordPress like this:

class WPUsersAPI implements UsersAPIInterface
{
  public function updateUserMetaAttributes($user_id, $meta)
  {
    foreach ($meta as $meta_key => $meta_value) {
      update_user_meta($user_id, $meta_key, $meta_value);
    }
  }
}

Finally, we may want to re-define a function to remove its ambiguities. For instance, WordPress function add_query_arg can receive parameters in two different ways:

  1. Using a single key and value: add_query_arg('key', 'value', 'http://example.com');
  2. Using an associative array: add_query_arg(['key1' => 'value1', 'key2' => 'value2'], 'http://example.com');

This becomes difficult to keep consistent across CMSs. Hence, our contract can define functions addQueryArg (singular) and addQueryArgs (plural) as to remove the ambiguity:

public function addQueryArg(string $key, string $value, string $url);
public function addQueryArgs(array $key_values, string $url);

Function parameters

We must also abstract the parameters to the function, making sure they make sense in a generic context. For each function to abstract, we must consider:

  • renaming and/or re-defining the parameters;
  • renaming and/or re-defining the attributes passed on array parameters.

For instance, WordPress function get_posts receives a unique parameter $args, which is an array of attributes. One of its attributes is fields which, when given the value "ids", makes the function return an array of IDs instead of an array of objects. However, I deem this implementation too specific for WordPress, and for a generic context I’d prefer a different solution: Convey this information through a separate parameter called $options, under attribute "return-type".

To accomplish this, we add parameter $options to the function in our contract:

interface PostAPIInterface
{
  public function getPosts($args, $options = []);
}

Instead of referencing WordPress constant value "ids" (which we can’t guarantee will be the one used in all other CMSs), we create a corresponding constant value for our abstracted application:

class Constants
{
  const RETURNTYPE_IDS = 'ids';
}

The WordPress implementation must map and recreate the parameters between the contract and the implementation:

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args, $options = []) {
    if ($options['return-type'] == Constants::RETURNTYPE_IDS) {
      $args['fields'] = 'ids';
    }
    return get_posts($args);
  }
}

And finally, we can execute the code through our contract:

$options = [
  'return-type' => Constants::RETURNTYPE_IDS,
];
$post_ids = $postsAPIService->getPosts($args, $options);

While abstracting the parameters, we should avoid transferring WordPress’s technical debt to our abstracted code, whenever possible. For instance, parameter $args from function get_posts can contain attribute 'post_type'. This attribute name is somewhat misleading, since it can receive one element (post_type => "post") but also a list of them (post_type => "post, event"), so this name should be in plural instead: post_types. When abstracting this piece of code, we can set our interface to expect attribute post_types instead, which will be mapped to WordPress’s post_type.

Similarly, different functions accept arguments with different names, even though these have the same objective, so their names can be unified. For instance, through parameter $args, WordPress function get_posts accepts attribute posts_per_page, and function get_users accepts attribute number. These attribute names can perfectly be replaced with the more generic attribute name limit.

It is also a good idea to rename parameters to make it easy to understand which ones belong to WordPress and which ones have been abstracted. For instance, we can decide to replace all "_" with "-", so our newly-defined argument post_types becomes post-types.

Applying these prior considerations, our abstracted code will look like this:

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args, $options = []) {
    ...
    if (isset($args['post-types'])) {
      $args['post_type'] = $args['post-types'];
      unset($args['post-types']);
    }
    if (isset($args['limit'])) { 
      $args['posts_per_page'] = $args['limit'];
      unset($args['limit']);
    }
    return get_posts($args);
  }
}

We can also re-define attributes to modify the shape of their values. For instance, WordPress parameter $args in function get_posts can receive attribute date_query, whose properties ("after", "inclusive", etc) can be considered specific to WordPress:

$date = current_time('timestamp');
$args['date_query'] = array(
  array(
    'after' => date('Y-m-d H:i:s', $date),
    'inclusive' => true,
  )
);

To unify the shape of this value into something more generic, we can re-implement it using other arguments, such as "date-from" and "date-from-inclusive" (this solution is not 100% convincing though, since it is more verbose than WordPress’s):

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args, $options = []) {
    ...
    if (isset($args['date-from'])) {
      $args['date_args'][] = [
        'after' => $args['date-from'],
        'inclusive' => false,
      ];
      unset($args['date-from']);
    }
    if (isset($args['date-from-inclusive'])) {
      $args['date_args'][] = [
        'after' => $args['date-from-inclusive'],
        'inclusive' => true,
      ];
      unset($args['date-from-inclusive']);
    }
    return get_posts($args);
  }
}

In addition, we need to consider if to abstract or not those parameters which are too specific to WordPress. For instance, function get_posts allows to order posts by attribute menu_order, which I don’t think it works in a generic context. Then, I’d rather not abstract this code and keep it on the CMS-specific package for WordPress.

Finally, we can also add argument types (and, since here we are, also return types) to our contract fuction, making it more understandable and allowing the code to fail in compilation time instead of during runtime:

interface PostAPIInterface
{
  public function getPosts(array $args, array $options = []): array;
}

States (and other constant values)

We need to make sure that all states have the same meaning in all CMSs. For instance, posts in WordPress can have one among the following states: "publish", "pending", "draft" or "trash". To make sure that the application references the abstracted version of the states and not the CMS-specific one, we can simply define a constant value for each of them:

class PostStates {
  const PUBLISHED = 'published';
  const PENDING = 'pending';
  const DRAFT = 'draft';
  const TRASH = 'trash';
}

As it can be seen, the actual constant values may or may not be the same as in WordPress: while "publish" was renamed as "published", the other ones remain the same.

For the implementation for WordPress, we convert from the agnostic value to the WordPress-specific one:

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args, $options = []) {
    ...
    if (isset($args['post-status'])) {
      $conversion = [
        PostStates::PUBLISHED => 'publish',
        PostStates::PENDING => 'pending',
        PostStates::DRAFT => 'draft',
        PostStates::TRASH => 'trash',
      ];
      $args['post_status'] = $conversion[$args['post-status']];
      unset($args['post-status']);
    }
    return get_posts($args);
  }
}

Finally, we can reference these constants throughout our CMS-agnostic application:

$args = [
  'post-status' => PostStates::PUBLISHED,
];
$posts = $postsAPIService->getPosts($args);

This strategy works under the assumption that all CMSs will support these states. If any CMS does not support a particular state (eg: "pending") then it should throw an exception whenever a corresponding functionality is invoked.

CMS helper functions

WordPress implements several helper functions that must also abstracted, such as make_clickable. Because these functions are very generic, we can implement a default behavior for them that works well in an abstract context, and which can be overridden if the CMS implements a better solution.

We first define the contract:

interface HelperAPIInterface
{
  public function makeClickable(string $text);
}

And provide a default behaviour for the helper functions through an abstract class:

abstract class AbstractHelperAPI implements HelperAPIInterface
{
  public function makeClickable(string $text) {
    return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9@:%_ .~#?&;//=] )!i', '$1', $text);
  }
}

Now, our application can either use this functionality or, if it runs on WordPress, use the WordPress-specific implementation:

class WPHelperAPI extends AbstractHelperAPI
{
  public function makeClickable(string $text) {
    return make_clickable($text);
  }
}

User permissions

For all CMSs which support user management, in addition to abstracting the corresponding functions (such as current_user_can and user_can in WordPress), we must also make sure that the user permissions (or capabilities) have the same effect across all CMSs. To achieve this, our abstracted application needs to explicitly state what is expected from the capability, and the implementation for each CMS must either satisfy it through one of its own capabilities or throw an exception if it can’t satisfy it. For instance, if the application needs to validate if the user can edit posts, it can represent it through a capability called "capability:editPosts", which is satisfied for WordPress through its capability "edit_posts".

This is still an instance of the “code against interfaces, not implementations” principle, however here we run against a problem: Whereas in PHP we can define interfaces and classes to model contracts and service providers (which works in compilation time, so that the code doesn’t compile if a class implementing an interface does not implement all functions defined in the interface), PHP offers no similar construct to validate that a contract capability (which is simply a string, such as "capability:editPosts") has been satisfied through a capability by the CMS. This concept, which I call a “loose contract”, will need to be handled by our application, on runtime.

To deal with “loose contracts”, I have created a service LooseContractService through which:

  • the application can define what “contract names” must be implemented, through function requireNames.
  • the CMS-specific implementations can satisfy those names, through function implementNames.
  • the application can get the implementation of a name through function getImplementedName.
  • the application can also inquire for all non-satisfied required names through function getNotImplementedRequiredNames, as to throw an exception or log the error if needed.

The service looks like this:

class LooseContractService
{
  protected $requiredNames = [];
  protected $nameImplementations = [];

  public function requireNames(array $names): void
  {
    $this->requiredNames = array_merge(
      $this->requiredNames,
      $names
    );
  }

  public function implementNames(array $nameImplementations): void
  {
    $this->nameImplementations = array_merge(
      $this->nameImplementations,
      $nameImplementations
    );
  }

  public function getImplementedName(string $name): ?string {
    return $this->nameImplementations[$name];
  }

  public function getNotImplementedRequiredNames(): array {
    return array_diff(
      $this->requiredNames,
      array_keys($this->nameImplementations)
    );
  }
}

The application, when initialized, can then establish loose contracts by requiring names:

$looseContractService = ContainerBuilderFactory::getInstance()->get('loose_contracts');
$looseContractService->requireNames([
  'capability:editPosts',
]);

And the CMS-specific implementation can satisfy these:

$looseContractService->implementNames([
  'capability:editPosts' => 'edit_posts',
]);

The application can then resolve the required name to the implementation from the CMS. If this required name (in this case, a capability) is not implemented, then the application may throw an exception:

$cmsCapabilityName = $looseContractService->getImplementedName('capability:editPosts');
if (!$cmsCapabilityName) {
  throw new Exception(sprintf(
    "The CMS has no support for capability "%s"",
    'capability:editPosts'
  ));
}
// Now can use the capability to check for permissions
$userManagementAPIService = ContainerBuilderFactory::getInstance()->get('user_management_api');
if ($userManagementAPIService->userCan($user_id, $cmsCapabilityName)) {
  ...
}

Alternatively, the application can also fail when first initialized if any one required name is not satisfied:

if ($notImplementedNames = $looseContractService->getNotImplementedRequiredNames()) {
  throw new Exception(sprintf(
    "The CMS has not implemented loose contract names %s",
    implode(', ', $notImplementedNames)
  ));
}

Application options

WordPress ships with several application options, such as those stored in table wp_options under entries "blogname", "blogdescription", "admin_email", "date_format" and many others. Abstracting application options involves:

  • abstraction the function getOption;
  • abstracting each of the required options, aiming to make the CMS satisfy the notion of this option (eg: if a CMS doesn’t have an option for the site’s description, it can’t return the site’s name instead).

Let’s solve these 2 actions in turn. Concerning function getOption, I believe that we can expect all CMSs to support storing and retrieving options, so we can place the corresponding function under a CMSCoreInterface contract:

interface CMSCoreInterface
{
  public function getOption($option, $default = false);
}

As it can be observed from the function signature above, I’m making the assumption that each option will also have a default value. However, I don’t know if every CMS allows setting default values for options. But it doesn’t matter since the implementation can simply return NULL then.

This function is resolved for WordPress like this:

class WPCMSCore implements CMSCoreInterface
{
  public function getOption($option, $default = false)
  {
    return get_option($option, $default);
  }
}

To solve the 2nd action, which is abstracting each needed option, it is important to notice that even though we can always expect the CMS to support getOption, we can’t expect it to implement each single option used by WordPress, such as "use_smiles" or "default_ping_status". Hence, we must first filter all options, and abstract only those that make sense in a generic context, such as "siteName" or "dateFormat".

Then, having the list of options to abstract, we can use a “loose contract” (as explained earlier on) and require a corresponding option name for each, such as "option:siteName" (resolved for WordPress as "blogname") or "option:dateFormat" (resolved as "date_format").

Database column names

In WordPress, when we are requesting data from function get_posts we can set attribute "orderby" in $args to order the results, which can be based on a column from the posts table (such as values "ID", "title", "date", "comment_count", etc), a meta value (through values "meta_value" and "meta_value_num") or other values (such as "post__in" and "rand").

Whenever the value corresponds to the table column name, we can abstract them using a “loose contract”, as explained earlier on. Then, the application can reference a loose contract name:

$args = [
  'orderby' => $looseContractService->getImplementedName('dbcolumn:orderby:posts:date'),
];
$posts = $postsAPIService->getPosts($args);

And this name is resolved for WordPress:

$looseContractService->implementNames([
  'dbcolumn:orderby:posts:date' => 'date',
]);

Now, let’s say that in our WordPress application we have created a meta value "likes_count" (which stores how many likes a post has) to order posts by popularity, and we want to abstract this functionality too. To order results by some meta property, WordPress expects an additional attribute "meta_key", like this:

$args = [
  'orderby' => 'meta_value',
  'meta_key' => 'likes_count',
];

Because of this additional attribute, I consider this implementation WordPress-specific and very difficult to abstract to make it work everywhere. Then, instead of generalizing this functionality, I can simply expect every CMS to add their own, specific implementation.

Let’s do that. First, I create a helper class to retrieve the CMS-agnostic query:

class QueryHelper
{
  public function getOrderByQuery()
  {
    return array(
      'orderby' => $looseContractService->getImplementedName('dbcolumn:orderby:posts:likesCount'),
    );
  }
}

The OctoberCMS-specific package can add a column "likes_count" to the posts table, and resolve name "dbcolumn:orderby:posts:likesCount" to "like_count" and it will work. The WordPress-specific package, though, must resolve "dbcolumn:orderby:posts:likesCount" as "meta_value" and then override the helper function to add the additional property "meta_key":

class WPQueryHelper extends QueryHelper
{
  public function getOrderByQuery()
  {
    $query = parent::getOrderByQuery();
    $query['meta_key'] = 'likes_count';
    return $query;
  }
}

Finally, we set-up the helper query class as a service in the ContainerBuilder, configure it to be resolved to the WordPress-specific class, and we obtain the query for ordering results:

$queryHelperService = ContainerBuilderFactory::getInstance()->get('query_helper');
$args = $queryHelperService->getOrderByQuery();
$posts = $postsAPIService->getPosts($args);

Abstracting the values for ordering results that do not correspond to column names or meta properties (such as "post__in" and "rand") seems to be more difficult. Because my application doesn’t use them, I haven’t considered how to do it, or even if it is possible. Then I took the easy way out: I have considered these to be WordPress-specific, hence the application makes them available only when running on WordPress.

Errors

When dealing with errors, we must consider abstracting the following elements:

  • the definition of an error;
  • error codes and messages.

Let’s review these in turn.

Definition of an error:

An Error is a special object, different than an Exception, used to indicate that some operation has failed, and why it failed. WordPress represents errors through class WP_Error, and allows to check if some returned value is an error through function is_wp_error.

We can abstract checking for an error:

interface CMSCoreInterface
{
  public function isError($object);
}

Which is resolved for WordPress like this:

class WPCMSCore implements CMSCoreInterface
{
  public function isError($object)
  {
    return is_wp_error($object);
  }
}

However, to deal with errors in our abstracted code, we can’t expect all CMSs to have an error class with the same properties and methods as WordPress’s WP_Error class. Hence, we must abstract this class too, and convert from the CMS error to the abstracted error after executing a function from the CMS.

The abstract error class Error is simply a slightly modified version from WordPress’s WP_Error class:

class Error {

  protected $errors = array();
  protected $error_data = array();

  public function __construct($code = null, $message = null, $data = null) 
  {
    if ($code) {
      $this->errors[$code][] = $message;
      if ($data) {
        $this->error_data[$code] = $data;
      }
    }
  }

  public function getErrorCodes()
  {
    return array_keys($this->errors);
  }

  public function getErrorCode()
  {    
    if ($codes = $this->getErrorCodes()) {
      return $codes[0];
    }

    return null;
  }

  public function getErrorMessages($code = null)
  {    
    if ($code) {
      return $this->errors[$code] ?? [];
    }

    // Return all messages if no code specified.
    return array_reduce($this->errors, 'array_merge', array());
  }

  public function getErrorMessage($code = null)
  {
    if (!$code) {
      $code = $this->getErrorCode();
    }
    $messages = $this->getErrorMessages($code);
    return $messages[0] ?? '';
  }

  public function getErrorData($code = null)
  {
    if (!$code) {
      $code = $this->getErrorCode();
    }

    return $this->error_data[$code];
  }

  public function add($code, $message, $data = null)
  {
    $this->errors[$code][] = $message;
    if ($data) {
      $this->error_data[$code] = $data;
    }
  }

  public function addData($data, $code = null)
  {
    if (!$code) {
      $code = $this->getErrorCode();
    }

    $this->error_data[$code] = $data;
  }

  public function remove($code)
  {
    unset($this->errors[$code]);
    unset($this->error_data[$code]);
  }
}

We implement a function to convert from the CMS to the abstract error through a helper class:

class WPHelpers
{
  public static function returnResultOrConvertError($result)
  {
    if (is_wp_error($result)) {
      // Create a new instance of the abstracted error class
      $error = new Error();
      foreach ($result->get_error_codes() as $code) {
        $error->add($code, $result->get_error_message($code), $result->get_error_data($code));
      }
      return $error;
    }
    return $result;
  }
}

And we finally invoke this method for all functions that may return an error:

class UserManagementService implements UserManagementInterface
{
  public function getPasswordResetKey($user_id)
  {
    $result = get_password_reset_key($user_id);
    return WPHelpers::returnResultOrConvertError($result);
  }
}
Error codes and messages:

Every CMS will have its own set of error codes and corresponding explanatory messages. For instance, WordPress function get_password_reset_key can fail due to the following reasons, as represented by their error codes and messages:

  1. "no_password_reset": Password reset is not allowed for this user.
  2. "no_password_key_update": Could not save password reset key to database.

In order to unify errors so that an error code and message is consistent across CMSs, we will need to inspect these and replace them with our custom ones (possibly in function returnResultOrConvertError explained above).

Hooks

Abstracting hooks involves:

  • the hook functionality;
  • the hooks themselves.

Let’s analyze these in turn.

Abstracting the hook functionality

WordPress offers the concept of “hooks”: a mechanism through which we can change a default behavior or value (through “filters”) and execute related functionality (through “actions”). Both Symfony and Laravel offer mechanisms somewhat related to hooks: Symfony provides an event dispatcher component, and Laravel’s mechanism is called events; these 2 mechanisms are similar, sending notifications of events that have already taken place, to be processed by the application through listeners.

When comparing these 3 mechanisms (hooks, event dispatcher and events) we find that WordPress’s solution is the simpler one to set-up and use: Whereas WordPress hooks enable to pass an unlimited number of parameters in the hook itself and to directly modify a value as a response from a filter, Symfony’s component requires to instantiate a new object to pass additional information, and Laravel’s solution suggests to run a command in Artisan (Laravel’s CLI) to generate the files containing the event and listener objects. If all we desire is to modify some value in the application, executing a hook such as $value = apply_filters("modifyValue", $value, $post_id); is as simple as it can get.

In the first part of this series, I explained that the CMS-agnostic application already establishes a particular solution for dependency injection instead of relying on the solution by the CMS, because the application itself needs this functionality to glue its parts together. Something similar happens with hooks: they are such a powerful concept that the application can greatly benefit by making it available to the different CMS-agnostic packages (allowing them to interact with each other) and not leave this wiring-up to be implemented only at the CMS level. Hence, I have decided to already ship a solution for the “hook” concept in the CMS-agnostic application, and this solution is the one implemented by WordPress.

In order to decouple the CMS-agnostic hooks from those from WordPress, once again we must “code against interfaces, not implementations”: We define a contract with the corresponding hook functions:

interface HooksAPIInterface
{
  public function addFilter(string $tag, $function_to_add, int $priority = 10, int $accepted_args = 1): void;
  public function removeFilter(string $tag, $function_to_remove, int $priority = 10): bool;
  public function applyFilters(string $tag, $value, ...$args);
  public function addAction(string $tag, $function_to_add, int $priority = 10, int $accepted_args = 1): void;
  public function removeAction(string $tag, $function_to_remove, int $priority = 10): bool;
  public function doAction(string $tag, ...$args): void;
}

Please notice that functions applyFilters and doAction are variadic, i.e. they can receive a variable amount of arguments through parameter ...$args. By combining this feature (which was added to PHP in version 5.6, hence it was unavailable to WordPress until very recently) with argument unpacking, i.e. passing a variable amount of parameters ...$args to a function, we can easily provide the implementation for WordPress:

class WPHooksAPI implements HooksAPIInterface
{
  public function addFilter(string $tag, $function_to_add, int $priority = 10, int $accepted_args = 1): void
  {
    add_filter($tag, $function_to_add, $priority, $accepted_args);
  }

  public function removeFilter(string $tag, $function_to_remove, int $priority = 10): bool
  {
    return remove_filter($tag, $function_to_remove, $priority);
  }

  public function applyFilters(string $tag, $value, ...$args)
  {
    return apply_filters($tag, $value, ...$args);
  }

  public function addAction(string $tag, $function_to_add, int $priority = 10, int $accepted_args = 1): void
  {
    add_action($tag, $function_to_add, $priority, $accepted_args);
  }

  public function removeAction(string $tag, $function_to_remove, int $priority = 10): bool
  {
    return remove_action($tag, $function_to_remove, $priority);
  }

  public function doAction(string $tag, ...$args): void
  {
    do_action($tag, ...$args);
  }
}

As for an application running on Symfony or Laravel, this contract can be satisfied by installing a CMS-agnostic package implementing WordPress-like hooks, such as this one, this one or this one.

Finally, whenever we need to execute a hook, we do it through the corresponding service:

$hooksAPIService = ContainerBuilderFactory::getInstance()->get('hooks_api');
$title = $hooksAPIService->applyFilters("modifyTitle", $title, $post_id);
Abstracting the hooks themselves

We need to make sure that, whenever a hook is executed, a consistent action will be executed no matter which is the CMS. For hooks defined inside of our application that is no problem, since we can resolve them ourselves, most likely in our CMS-agnostic package. However, when the hook is provided by the CMS, such as action "init" (triggered when the system has been initialized) or filter "the_title" (triggered to modify a post’s title) in WordPress, and we invoke these hooks, we must make sure that all other CMSs will process them correctly and consistently. (Please notice that this concerns hooks that make sense in every CMS, such as "init"; certain other hooks can be considered too specific to WordPress, such as filter "rest_{$this->post_type}_query" from a REST controller, so we don’t need to abstract them.)

The solution I found is to hook into actions or filters defined exclusively in the application (i.e. not in the CMS), and to bridge from CMS hooks to application hooks whenever needed. For instance, instead of adding an action for hook "init" (as defined in WordPress), any code in our application must add an action on hook "cms:init", and then we implement the bridge in the WordPress-specific package from "init" to "cms:init":

$hooksAPIService->addAction('init', function() use($hooksAPIService) {
  $hooksAPIService->doAction('cms:init');
});

Finally, the application can add a “loose contract” name for "cms:init", and the CMS-specific package must implement it (as demonstrated earlier on).

Routing

Different frameworks will provide different solutions for routing (i.e. the mechanism of identifying how the requested URL will be handled by the application), which reflect the architecture of the framework:

  • In WordPress, URLs map to database queries, not to routes.
  • Symfony provides a Routing component which is independent (any PHP application can install it and use it), and which enables to define custom routes and which controller will process them.
  • Laravel’s routing builds on top of Symfony’s routing component to adapt it to the Laravel framework.

As it can be seen, WordPress’s solution is the outlier here: the concept of mapping URLs to database queries is tightly coupled to WordPress’s architecture, and we would not want to restrict our abstracted application to this methodology (for instance, October CMS can be set-up as a flat-file CMS, in which case it doesn’t use a database). Instead, it makes more sense to use Symfony’s approach as its default behavior, and allow WordPress to override this behavior with its own routing mechanism.

(Indeed, while WordPress’s approach works well for retrieving content, it is rather inappropriate when we need to access some functionality, such as displaying a contact form. In this case, before the launch of Gutenberg, we were forced to create a page and add a shortcode "[contact_form]" to it as content, which is not as clean as simply mapping the route to its corresponding controller directly.)

Hence, the routing for our abstracted application will not be based around the modeled entities (post, page, category, tag, author) but purely on custom-defined routes. This should already work perfectly for Symfony and Laravel, using their own solutions, and there is not much for us to do other than injecting the routes with the corresponding controllers into the application’s configuration.

To make it work in WordPress, though, we need to take some extra steps: We must introduce an external library to handle routing, such as Cortex. Making use of Cortex, the application running on WordPress can have it both ways:

  • if there is a custom-defined route matching the requested URL, use its corresponding controller.
  • if not, let WordPress handle the request in its own way (i.e. retrieving the matched database entity or returning a 404 if no match is successful).

To implement this functionality, I have designed the contract CMSRoutingInterface to, given the requested URL, calculate two pieces of information:

  • the actual route, such as contact, posts or posts/my-first-post.
  • the nature of the route: core nature values "standard", "home" and "404", and additional nature values added through packages such as "post" through a “Posts” package or "user" through a “Users” package.

The nature of the route is an artificial construction that enables the CMS-agnostic application to identify if the route has extra qualities attached to it. For instance, when requesting the URL for a single post in WordPress, the corresponding database object post is loaded into the global state, under global $post. It also helps identify which case we want to handle, to avoid inconsistencies. For instance, we could have defined a custom route contact handled by a controller, which will have nature "standard", and also a page in WordPress with slug "contact", which will have nature "page" (added through a package called “Pages”). Then, our application can prioritize which way to handle the request, either through the controller or through a database query.

Let’s implement it. We first define the service’s contract:

interface CMSRoutingInterface
{
  public function getNature();
  public function getRoute();
}

We can then define an abstract class which provides a base implementation of these functions:

abstract class AbstractCMSRouting implements CMSRoutingInterface
{
  const NATURE_STANDARD = 'standard';
  const NATURE_HOME = 'home';
  const NATURE_404 = '404';

  public function getNature()
  {
    return self::NATURE_STANDARD;
  }

  public function getRoute()
  {
    // By default, the URI path is already the route (minus parameters and trailing slashes)
    $route = $_SERVER['REQUEST_URI'];
    $params_pos = strpos($route, '?');
    if ($params_pos !== false) {
       $route = substr($route, 0, $params_pos);
    }
    return trim($route, '/');
  }
}

And the implementation is overriden for WordPress:

class WPCMSRouting extends AbstractCMSRouting
{
  const ROUTE_QUERY = [
    'custom_route_key' => 'custom_route_value',
  ];
  private $query;
  private function init()
  {
    if (is_null($this->query)) {
      global $wp_query;
      $this->query = $wp_query;
    }
  }

  private function isStandardRoute() {
    return !empty(array_intersect($this->query->query_vars, self::ROUTE_QUERY));
  }

  public function getNature()
  {
    $this->init();
    if ($this->isStandardRoute()) {
      return self::NATURE_STANDARD;
    } elseif ($this->query->is_home() || $this->query->is_front_page()) {
      return self::NATURE_HOME;
    } elseif ($this->query->is_404()) {
      return self::NATURE_404;
    }

    // Allow components to implement their own natures
    $hooksAPIService = ContainerBuilderFactory::getInstance()->get('hooks_api');
    return $hooksAPIService->applyFilters(
      "nature",
      parent::getNature(),
      $this->query
    );
  }
}

In the code above, please notice how constant ROUTE_QUERY is used by the service to know if the route is a custom-defined one, as configured through Cortex:

$hooksAPIService->addAction(
  'cortex.routes', 
  function(RouteCollectionInterface $routes) {  
    // Hook into filter "routes" to provide custom-defined routes
    $appRoutes = $hooksAPIService->applyFilters("routes", []);
    foreach ($appRoutes as $route) {
      $routes->addRoute(new QueryRoute(
        $route,
        function (array $matches) {
          return WPCMSRouting::ROUTE_QUERY;
        }
      ));
    }
  }
);

Finally, we add our routes through hook "routes":

$hooksAPIService->addFilter(
  'routes',
  function($routes) {
    return array_merge(
      $routes,
      [
        'contact',
        'posts',
      ]
    );
  }
);

Now, the application can find out the route and its nature, and proceed accordingly (for instance, for a "standard" nature invoke its controller, or for a "post" nature invoke WordPress’s templating system):

$cmsRoutingService = ContainerBuilderFactory::getInstance()->get('routing');
$nature = $cmsRoutingService->getNature();
$route = $cmsRoutingService->getRoute();
// Process the requested route, as appropriate
// ...

Object properties

A rather inconvenient consequence of abstracting our code is that we can’t reference the properties from an object directly, and we must do it through a function instead. This is because different CMSs will represent the same object as containing different properties, and it is easier to abstract a function to access the object properties than to abstract the object itself (in which case, among other disadvantages, we may have to reproduce the object caching mechanism from the CMS). For instance, a post object $post contains its ID under $post->ID in WordPress and under $post->id in October CMS. To resolve this property, our contract PostObjectPropertyResolverInterface will contain function getId:

interface PostObjectPropertyResolverInterface {
  public function getId($post);
}

Which is resolved for WordPress like this:

class WPPostObjectPropertyResolver implements PostObjectPropertyResolverInterface {
  public function getId($post)
  {
    return $post->ID;
  }
}

Similarly, the post content property is $post->post_content in WordPress and $post->content in October CMS. Our contract will then allow to access this property through function getContent:

interface PostObjectPropertyResolverInterface {
  public function getContent($post);
}

Which is resolved for WordPress like this:

class WPPostObjectPropertyResolver implements PostObjectPropertyResolverInterface {
  public function getContent($post)
  {
    return $post->post_content;
  }
}

Please notice that function getContent receives the object itself through parameter $post. This is because we are assuming the content will be a property of the post object in all CMSs. However, we should be cautious on making this assumption, and decide on a property by property basis. If we don’t want to make the previous assumption, then it makes more sense for function getContent to receive the post’s ID instead:

interface PostObjectPropertyResolverInterface {
  public function getContent($post_id);
}

Being more conservative, the latter function signature makes the code potentially more reusable, however it is also less efficient, because the implementation will still need to retrieve the post object:

class WPPostObjectPropertyResolver implements PostObjectPropertyResolverInterface {
  public function getContent($post_id)
  {
    $post = get_post($post_id);
    return $post->post_content;
  }
}

In addition, some properties may be needed in their original value and also after applying some processing; for these cases, we will need to implement a corresponding extra function in our contract. For instance, the post content needs be accessed also as HTML, which is done through executing apply_filters('the_content', $post->post_content) in WordPress, or directly through property $post->content_html in October CMS. Hence, our contract may have 2 functions to resolve the content property:

interface PostObjectPropertyResolverInterface {
  public function getContent($post_id); // = raw content
  public function getHTMLContent($post_id);
}

We must also be concerned with abstracting the value that the property can have. For instance, a comment is approved in WordPress if its property comment_approved has the value "1". However, other CMSs may have a similar property with value true. Hence, the contract should remove any potential inconsistency or ambiguity:

interface CommentObjectPropertyResolverInterface {
  public function isApproved($comment);
}

Which is implemented for WordPress like this:

class WPCommentObjectPropertyResolver implements CommentObjectPropertyResolverInterface {
  public function isApproved($comment)
  {
    return $comment->comment_approved == "1";
  }
}

Global state

WordPress sets several variables in the global context, such as global $post when querying a single post. Keeping variables in the global context is considered an anti-pattern, since the developer could unintentionally override their values, producing bugs that are difficult to track down. Hence, abstracting our code gives us the chance to implement a better solution.

An approach we can take is to create a corresponding class AppState which simply contains a property to store all variables that our application will need. In addition to initializing all core variables, we enable components to initialize their own ones through hooks:

class AppState
{
  public static $vars = [];

  public static function getVars()
  {
    return self::$vars;
  }

  public static function initialize()
  {
    // Initialize core variables
    self::$vars['nature'] = $cmsRoutingService->getNature();
    self::$vars['route'] = $cmsRoutingService->getRoute();

    // Initialize $vars through hooks
    self::$vars = $hooksAPIService->applyFilters("AppState:init", self::$vars);

    return self::$vars;
  }
}

To replace global $post, a hook from WordPress can then set this data through a hook. A first step would be to set the data under "post-id":

$hooksAPIService->addFilter(
  "AppState:init", 
  function($vars) {
    if (is_single()) {
      global $post;
      $vars['post-id'] => $post->ID;
    }
    return $vars;
  }
);

However, we can also abstract the global variables: instead of dealing with fixed entities (such as posts, users, comments, etc), we can deal with the entity in a generic way through "object-id", and we obtain its properties by inquiring the nature of the requested route:

$hooksAPIService->addFilter(
  "AppState:init", 
  function($vars) {
    if ($vars['nature'] == 'post') {
      global $post;
      $vars['object-id'] => $post->ID;
    }
    return $vars;
  }
);

From now own, if we need to display a property of the current post, we access it from the newly defined class instead of the global context:

$vars = AppState::getVars();
$object_id = $vars['object-id'];
// Do something with it
// ...

Entity models (meta, post types, pages being posts, and taxonomies —tags and categories—)

We must abstract those decisions made for WordPress concerning how its entities are modeled. Whenever we consider that WordPress’s opinionatedness makes sense in a generic context too, we can then replicate such a decision for our CMS-agnostic code.

Meta:

As mentioned earlier, the concept of “meta” must be decoupled from the model entity (such as “post meta” from “posts”), so if a CMS doesn’t provide support for meta, it can then discard only this functionality.

Then, package “Post Meta” (decoupled from, but dependent on, package “Posts”) defines the following contract:

interface PostMetaAPIInterface
{
  public function getMetaKey($meta_key);
  public function getPostMeta($post_id, $key, $single = false);
  public function deletePostMeta($post_id, $meta_key, $meta_value = '');
  public function addPostMeta($post_id, $meta_key, $meta_value, $unique = false);
  public function updatePostMeta($post_id, $meta_key, $meta_value);
}

Which is resolved for WordPress like this:

class WPPostMetaAPI implements PostMetaAPIInterface
{
  public function getMetaKey($meta_key)
  {
    return '_'.$meta_key;
  }
  public function getPostMeta($post_id, $key, $single = false)
  {
    return get_post_meta($post_id, $key, $single);
  }
  public function deletePostMeta($post_id, $meta_key, $meta_value = '')
  {
    return delete_post_meta($post_id, $meta_key, $meta_value);
  }
  public function addPostMeta($post_id, $meta_key, $meta_value, $unique = false)
  {
    return add_post_meta($post_id, $meta_key, $meta_value, $unique);
  }
  public function updatePostMeta($post_id, $meta_key, $meta_value)
  {
    return update_post_meta($post_id, $meta_key, $meta_value);
  }
}
Post types:

I have decided that WordPress’s concept of a custom post type, which allows to model entities (such as an event or a portfolio) as extensions of posts, can apply in a generic context, and as such, I have replicated this functionality in the CMS-agnostic code. This decision is controversial, however, I justify it because the application may need to display a feed of entries of different types (such as posts, events, etc) and custom post types make such implementation feasible. Without custom post types, I would expect the application to need to execute several queries to bring the data for every entity type, and the logic would get all muddled up (for instance, if fetching 12 entries, should we fetch 6 posts and 6 events? but what if the events were posted much earlier than the last 12 posts? and so on).

What happens when the CMS doesn’t support this concept? Well, nothing serious happens: a post will still indicate its custom post type to be a “post”, and no other entities will inherit from the post. The application will still work properly, just with some slight overhead from the unneeded code. This is a trade-off that, I believe, is more than worth it.

To support custom post types, we simply add a function getPostType in our contract:

interface PostAPIInterface
{
  public function getPostType($post_id);
}

Which is resolved for WordPress like this:

class WPPostAPI implements PostAPIInterface
{
  public function getPostType($post_id) {
    return get_post_type($post_id);
  }
}
Pages being posts:

While I justify keeping custom post types in order to extend posts, I don’t justify a page being a post, as it happens in WordPress, because in other CMSs these entities are completely decoupled and, more importantly, a page may have higher rank than a post, so making a page extend from a post would make no sense. For instance, October CMS ships pages in its core functionality, but posts must be installed through plugins.

Hence we must create separate contracts for posts and pages, even though they may contain the same functions:

interface PostAPIInterface
{
  public function getTitle($post_id);
}

interface PageAPIInterface
{
  public function getTitle($page_id);
}

To resolve these contracts for WordPress and avoid duplicating code, we can implement the common functionality through a trait:

trait WPCommonPostFunctions
{
  public function getTitle($post_id)
  {
    return get_the_title($post_id);
  }
}

class WPPostAPI implements PostAPIInterface
{
  use WPCommonPostFunctions;
}

class WPPageAPI implements PageAPIInterface
{
  use WPCommonPostFunctions;
}
Taxonomies (tags and categories):

Once again, we can’t expect all CMSs to support what is called taxonomies in WordPress: tags and categories. Hence, we must implement this functionality through a package “Taxonomies”, and, assuming that tags and categories are added to posts, make this package dependent on package “Posts”.

interface TaxonomyAPIInterface
{
  public function getPostCategories($post_id, $options = []);
  public function getPostTags($post_id, $options = []);
  public function getCategories($query, $options = []);
  public function getTags($query, $options = []);
  public function getCategory($cat_id);
  public function getTag($tag_id);
  ...
}

We could have decided to create two separate packages “Categories” and “Tags” instead of “Taxonomies”, however, as the implementation in WordPress makes evident, a tag and a category are basically the same concept of entity with only a tiny difference: categories are hierarchical (i.e. a category can have a parent category), but tags are not. Then, I consider that it makes sense to keep this concept for a generic context, and shipped under a single package “Taxonomies”.

We must pay attention that certain functionalities involve both posts and taxonomies, and these must be appropriately decoupled. For instance, in WordPress we can retrieve posts that were tagged "politics" by executing get_posts(['tag' => "politics"]). In this case, while function getPosts must be implemented in package “Posts”, filtering by tags must be implemented in package “Taxonomies”. To accomplish this separation, we can simply execute a hook in the implementation of function getPosts for WordPress, allowing any component to modify the arguments before executing get_posts:

class WPPostAPI implements PostAPIInterface
{
  public function getPosts($args) {
    $args = $hooksAPIService->applyFilters("modifyArgs", $args);
    return get_posts($args);
  }
}

And finally we implement the hook in package “Taxonomies for WordPress”:

$hooksAPIService->addFilter(
  'modifyArgs',
  function($args) {
    if (isset($args['tags'])) {
      $args['tag'] = implode(',', $args['tags']);
      unset($args['tags']);
    }
    if (isset($args['categories'])) {
      $args['cat'] = implode(',', $args['categories']);
      unset($args['categories']);
    }
    return $args;
  }
);

Please notice that in the abstracted code the attributes were re-defined (following the recommendations for abstracting function parameters, explained earlier on): "tag" must be provided as "tags" and "cat" must be provided as "categories" (shifting the connotation from singular to plural), and these values must be passed as arrays (i.e. removed accepting comma-separated strings as in WordPress, to add consistency).

Translation

Because calls to translate strings are spread all over the application code, translation is not a functionality that we can opt out from, and we should make sure that the other frameworks are compatible with our chosen translation mechanism.

In WordPress, which implements internationalization through gettext, we are required to set-up translation files for each locale code (such as ‘fr_FR’, which is the code for french language from FRance), and these can be set under a text domain (which allows themes or plugins to define their own translations without fear of collision with the translations from other pieces of code). We don’t need to check for support for placeholders in the string to translate (such as when doing sprintf(__("Welcome %s"), $user_name)), because function sprintf belongs to PHP and not to the CMS, so it will always work.

Let’s check if the other frameworks support the required two properties, i.e. getting the translation data for a specific locale composed of language and country, and under a specific text domain:

  • Symfony’s translation component supports these two properties.
  • The locale used in Laravel’s localization involves the language but not the country, and text domains are not supported (they could be replicated through overriding package language files, but the domain is not explicitly set, so the contract and the implementation would be inconsistent with each other).

However, luckily there is library Laravel Gettext which can replace Laravel’s native implementation with Symfony’s translation component. Hence, we got support for all frameworks, and we can rely on a WordPress-like solution.

We can then define our contract mirroring the WordPress function signatures:

interface TranslationAPIInterface
{
  public function __($text, $domain = 'default');
  public function _e($text, $domain = 'default');
}

The implementation of the contract for WordPress is like this:

class WPTranslationAPI implements TranslationAPIInterface
{
  public function __($text, $domain = 'default')
  {
    return __($text, $domain);
  }
  public function _e($text, $domain = 'default')
  {
    _e($text, $domain);
  }
}

And to use it in our application, we do:

$translationAPI = ContainerBuilderFactory::getInstance()->get('translation_api');
$text = $translationAPI->__("translate this", "my-domain");

Media

WordPress has media management as part of its core functionality, which represents a media element as an entity all by itself, and allows to manipulate the media element (such as cropping or resizing images), but we can’t expect all CMSs to have similar functionality. Hence, media management must be decoupled from the CMS core functionality.

For the corresponding contract, we can mirror the WordPress media functions, but removing WordPress’s opinionatedness. For instance, in WordPress, a media element is a post (with post type "attachment"), but for the CMS-agnostic code it is not, hence the parameter must be $media_id (or $image_id) instead of $post_id. Similarly, WordPress treats media as attachments to posts, but this doesn’t need to be the case everywhere, hence we can remove the word “attachment” from the function signatures. Finally, we can decide to keep the $size of the image in the contract; if the CMS doesn’t support creating multiple image sizes for an image, then it can just fall back on its default value NULL and nothing grave happens:

interface MediaAPIInterface
{
  public function getImageSrcAndDimensions($image_id, $size = null): array;
  public function getImageURL($image_id, $size = null): string;
}

The response by function getImageSrcAndDimensions can be asbtracted too, returning an array of our own design instead of simply re-using the one from the WordPress function wp_get_attachment_image_src:

class WPMediaAPI implements MediaAPIInterface
{
  public function getImageSrcAndDimensions($image_id, $size = null): array
  {
    $img_data = wp_get_attachment_image_src($image_id, $size);
    return [
      'src' => $img_data[0],
      'width' => $img_data[1],
      'height' => $img_data[2],
    ];
  }
  public function getImageURL($image_id, $size = null): string
  {
    return wp_get_attachment_image_url($image_id, $size);
  }
}

Conclusion

Setting-up a CMS-agnostic architecture for our application can be a painful endeavor. As it was demonstrated in this article, abstracting all the code was a lengthy process, taking plenty of time and energy to achieve, and it is not even finished yet. I wouldn’t be surprised if the reader is intimidated by the idea of going through this process in order to convert a WordPress application into a CMS-agnostic one. If I hadn’t done the abstraction myself, I would certainly be intimidated too.

My suggestion is for the reader is to analyze if going through this process makes sense based on a project-by-project basis. If there is no need whatsoever to port an application to a different CMS, then you will be right to stay away from this process and stick to the WordPress way. However, if you do need to migrate an application away from WordPress and want to reduce the effort required, or if you already need to maintain several codebases which would benefit from code reusability, or even if you may migrate the application sometime in the future and you have just started a new project, then this process is for you. It may be painful to implement, but well worth it. I know because I’ve been there. But I’ve survived, and I’d certainly do it again. Thanks for reading.

Smashing Editorial(dm, yk, il)

how-to-add-maps-to-your-wordpress-cf7-contact-form

Difficulty:BeginnerLength:ShortLanguages:

A contact form is a quick way for users to get in touch with you. Some of the benefits of a contact form include the following.

Reduce Spam

One of the ways to cut down on spam is to use a contact form. You will no longer have to put your email address out there, which makes it harder for people to send you spam mail.

Collect Specific Information

A contact form allows you to request specific information or control the information a user provides.  Since you are at liberty to add or remove any form field you wish, you can make particular fields required with a contact form.

Collect Leads

People find it easy to fill a contact form as opposed to calling or sending an email. Having a contact form is an effective way to collect leads and increase conversion rates. Even the simplest contact form can lead to an increase in leads.

Obtain Feedback

You can use a contact form to create a specific form geared towards obtaining questions and feedback from customers, especially for new products or services. This kind of information can be used to make better marketing decisions or improvements.

Obtain Quotes

You can also use a contact form to allow customers to request quotes, especially for service-oriented businesses. Or you can use it to receive quotes from customers.

Communication

A contact form provides an easy way for customers to get in touch with you. Instead of scouring through your website to obtain your email, you can place the form in an accessible page where users will find it easy to contact you.

Premium Contact Form Plugins

Free plugins are great when you’re getting started with WordPress, but if you want to go to the next level with your sites and save yourself time while you’re doing it, you should consider a premium contact form plugin from CodeCanyon.

What We’ll Be Building

This tutorial will show you how to add Google Maps to a contact form using Contact Form 7 and the Google Maps Extension for CF7 WordPress plugin. By the end of the tutorial, we should have something like this:

The completed contact form with Google Maps extension

CF7 Plugin for Free Contact Forms

Contact Form 7 provides a simple and flexible contact form for your WordPress website. You can customize the design of the form and configure where information is sent when users contact you. Contact Form 7 is very popular and hence has tons of free and paid add-ons that provide extra features such as Dropbox integration, maps integration, and so on.

The plugin comes with additional features such as AJAX submission, Akismet spam filtering, form upload files, and even the ability to add a CAPTCHA to the form. The most significant advantage of this form is that it’s free to use.

Why Use Contact Form 7?

Many plugins can help you create a contact form for your WordPress website; Contact Form 7 is one of those plugins. Since it’s flexible and easy to use, Contact Form 7 is considered the top choice when choosing a contact form.

This plugin provides a straightforward and uncomplicated way to get set up, especially if you don’t know much about coding.

Install the CF7 Contact Form

The fastest way to install the CF7 contact form plugin is to use the plugin search feature from within WordPress. Go to Plugins > Add New and search for CF7 contact form with the search bar. Click on it and click Install. After the plugin has installed, click on the Activate link to activate the plugin.

Google Maps Extension for CF7

The Google Maps Extension for CF7 provides a great way to enhance your form by adding a map field to it. This allows you to obtain the user’s location. Some of the notable features of this plugin include:

  • collect user information via Google Maps
  • visitors can drop markers or draw any number of rectangles, circles, and polygons on the map
  • automatically obtain a KML file based on the visitor’s location
  • customize Google Maps according to your needs
  • fully responsive maps
  • choose the map type, i.e. Roadmap, Satellite, Hybrid, or Terrain
  • customize attributes such as colors, shapes, thickness, stroke color, and opacity

Purchase and download the Google Maps Extension for CF7. You can find your installable WordPress files in the download section of your account.

Once you download the WordPress files, log in to your WordPress site, and install the plugin. Go to Plugins > Add New and upload the WordPress zip file you got from CodeCanyon. After uploading, click Install Now, wait a few seconds, and then click Activate. You can now start using the plugin.

Google maps are now integrated with the contact form, as shown below.

Google Maps integration in CF7

Configurations

To add a map to our contact form, we need to generate a Google Maps API Key.

To obtain an API key:

  • Go to the Google Cloud Console and sign in with your Google account.
  • Select or create a new project.
  • Navigate to the Credentials page, and click Create credentials > API key
  • Copy and paste the key to your WordPress site under CF7 Google maps settings.
Getting a Google Maps API key

The Google Maps extension for CF7 provides various ways in which you can configure maps.

  • Users can mark their current location using a marker or highlight an area. They can also draw polygons, polylines, circles, and rectangles.
  • The user’s location inputs can be sent in the default CF7 email along with other form data. View the location data directly on Google Maps.
  • Automatically get the user’s input data as a KML file in the email and view it easily using an online KML file viewer.
  • You can change map types, zoom level, and other map attributes according to your requirements. You can also center the user’s location.

Edit the rest of the settings such as markers, map types, and other attributes from the settings page, as shown below, and save the changes.

Maps and markers setttings

Create a Contact Form With a Map

Go to  Contact > Add New from your WordPress Dashboard menu. Contact Form 7 comes pre-configured with a ready-to-use template which looks like this:

The default Contact Form 7 template

To add a map field, click the Google Maps button and you should see a popup like this:

Google Maps popup

Click on Insert Tag, and the map appears as a field on your form. Your form should now look something like this:

The default contact form with a map

Storage

Go to the Mail tab and paste the [maps] shortcode in your email component to receive maps data in an email. Save all the changes. Each form, once created, generates a unique shortcode that you will use to embed it on a page.

Embed the Contact Form With Map Upload in a Page

The last step is to embed the form on a page or any other place you want it to appear. Go to Pages > Add New, give the page a title, and paste the shortcode on the body of the page as shown below.

The completed contact form shortcode

The complete form with a map will look like this:

The completed form with a map

As you can see, visitors can put markers on their location or use the search feature to search for their location. They can also draw shapes and zoom in and out just like on a normal map.

Conclusion

Knowing the locations of visitors filling out your WordPress forms can help you identify who is coming to your site and showing interest. Collecting location information can help you make better decisions about the type of services or products you offer. 

wordpress-designers-on-dribbble-worth-following

Biljana Jovanovic

Want to give your website a boost and transform its visual identity? Need a helping hand that will make your journey to the authentic website all fun and games? Start at Dribbble. Although there are many great online resources with free vector illustrations and free stock photos, you won’t get far if you are creating your website from scratch, with zero design knowledge. This is where Dribbble enters the scene. This famous platform is a way to go for everyone who wants to find and showcase creative work. In other words, Dribbble is a perfect place to share portfolio and get noticed by both designer experts and potential clients. If you’re looking for talented individuals or famous design studios that can help you with your new website’s look or any other design matter, Dribbble is the right starting point. From animation, illustration, print and product design, to typography and web design, this website features all the design types and elements you might need. If you are particularly interested in WordPress, we have a real treat for you: a curated list of top 8 WordPress designers on Dribbble! The order is random, so your perfect candidate may be at the bottom of our list. So, make sure you read everything from top to bottom.

Milica Andjelkovic

Milica is a designer of all shapes and forms, but her work is primarily focused on web design. Versatile and professional, her Dribbble work selection covers everything from the portfolio, and architecture, to travel, and yoga niche. What makes Milica’s design style characteristics is the mixture of great color combinations and amazing interactive animations. Have a look at Sekko for example. The perfect combination of pastel colors and progressive typography makes each homepage of this theme a little piece of art. Another relevant sample is Mixtape. Thanks to vibrant colors this eye-catching template particularly made for musicians is great for a lively presentation of any other kind.

Ishtiaq Khan Parag

As a product designer at Elegant Themes, this Bangladesh based visual guru, definitely knows how to stand out from the crowd. The facts he works for the creators of the most-widely used premium WordPress theme, says enough. With 7k followers on Dribbble and a portfolio that attract attention, Ishtiag is one of the designers you can’t ignore. Take Art Gallery template he created for Divi Theme as an example. This modern, elegant layout crafted in a minimal manner is almost a paradigm for everyone who wants that perfect balance of simplicity and bold details. In a similar style he also designed Elachii Landing Page. Gentle colors and tiny details are what make this template an absolute winner. As Ishtiag always goes one step ahead, his work is a proven inspiration resource for many design enthusiasts.

Stevan Ivic

This talented design professional from Qode Interactive demonstrated great attention to detail in his works. Specialized in graphic design, illustration and logo design, Stevan creates lovely illustrations nobody can ignore. Here you can check out Bolge, all-in-one portfolio theme with dominant navy, gentle pink and white colors. Meticulously crafted, this professional template is great for any creative niche – from marketing and SEO agencies, to creative design studios and branding companies. Also, we recommend you to check out Krafti, a stylish theme made for anyone who creates arts and crafts. Nice colors and gentle shapes of this theme will make you love Stevan’s work.

JayJay

JayJay is another professional web designer with a great reputation on Dribbble. His flawless works are designed to perfectly fit your website. Besides websites, this talented artist also covers mobile apps, project management dashboards and much more. The versatility of his work and eye for detail are probably the reason behind his amazing list of clients. JayJay has collaborated with some of the leading global brands so it’s not surprising many designers follow him to get inspired. Ocolus sums up his style perfectly. Well-balanced elements and carefully chosen colors are the reasons JayJay is so well accepted at Dribbble.

Jelisaveta Stosic

Jelisaveta is another UX designer that made web designer her favorite playground. Her great graphic design skills and strong visual sense is visible in all the works she shared on Dribbble. Let’s take a closer look at Mintus, a bright, dazzling theme for creatives. As its name suggests, this theme brings a lot of mint elements and design details. Another example that shows Jelisaveta’s talents is Dor. Made for architects, this elegant theme is a great choice for everyone who prefers a simple, minimalistic design style. Dor also proves that less is definitely more.

Marina Pavlovic

Marina is UI/UX designers with over 5 years of experience in creating beautiful WordPress themes. Her contemporary, progressive style always seems to surprise with little, eye-catching details. Also, Marina is one of the contributors to Bridge, a Theme Forest creative bestseller. If you fancy a modern website look and feel, you should definitely check out other works of this designer. For instance, BoostUp – SEO Marketing Agency Theme, which is a great example of a sophisticated, yet vibrant business fashion. On the other hand, for all sweets lovers Marina crafted Panaderia, a delicious theme for every bakery and pastry shop. This beautifully designed theme has tons of lovely templates, all with balanced colors and trendy typography.

Beatris Veres

Based in Romania, but open to collaborating with clients worldwide, Beatris is a member of INK9 Creative Agency. Her rich colors and their amazing combinations, show all the power of this visual artist. Although you can see different aspects of Beatris’ work on Dribbble, this time we want to shed some light on the works she did for Bad Jokes and Dance Festival. If you like simple, yet effective forms and bright colors with dominant red, yellow, purple and white, the first example is for you. On the other side, Dance festival layout demonstrates a strong sense of mixing shapes, images and bold typography.

Mateusz Madura

Mateusz is specialized in creating websites, mobile applications and branding in general. His sophisticated style and talent for bringing different design forms under one aesthetic umbrella, never stops to surprise. Although Mateusz shares multiuse templates, ideal for different niches, each concept displayed on Dribbble is one, independent story. Every work example this designer shared is well-thought-out, authentic and ready to shine. However, our favorites are Seabedee and VidyArk – both made to help your WordPress site bloom.

Dribbble is a special place for the creative community with an endless amount of amazing design works. It’s also a perfect starting point for everyone looking for talented freelancers for part-time or full-time projects. We hope this list got you inspired or helped you find the right designer for hire. Follow us for more as we’ll keep on updating it with fresh authors.

We hope this article was helpful. If you liked it, feel free to check out some of these articles as well!

10-best-wordpress-backup-plugins-to-protect-your-website

The WordPress websites can be vulnerable to bugging; resultantly, the data gets affected or gets completely crashed. The WordPress backup plugins, however, protect the data from getting affected. You certainly need to provide your WordPress website with the backup support for the recovery of the website if it gets trashed by the hacker or by any other factor. Due to the non-existence of backup support, you certainly have to recreate a website by consuming much effort and time.

Manual Backup Vs Plugin Backup

It is noteworthy here that providing the best WordPress backup plugin support to your website is very essential; however, it is at your disposal to opt for manual backup or plugin backup. To your information, the manual backup also works well; nevertheless, you need to be an expert in this regard. It is a technical task that does not afford even the slightest error. On the other hand, the plugin backup needs no expertise on your part; many plugins come with an automatic setting. It is worth mentioning here that all plugins are not the same. One can be different from others.

Some Important Instructions before Choosing Plugin

The first and foremost things are to decide whether you opt for a free plugin or paid plugin. Some of the plugins are free with limited features; to avail the advanced features, you have to pay for them. Having decided to use a plugin; you still need to know some basic things about a plugin; for example, it should be user-friendly; no detailed instructions should be there to confuse you while installing it. Moreover, the WordPress backup plugin should run automatically; you need not do the process manually after a week or two.

Provide the WordPress Backup Plugin Support

The plugin is required to provide full-site backup support; the WordPress backup plugin needs to support the complete website; not only to a text portion but also to the videos and other folders carrying important technical information.

Following are the Best WordPress Backup Plugins.

1. VaultPress

Vaultpress


Automattic Inc. provides the service of it directly. Backpack has to be installed first to subscribe to the vault press. Once the service is activated your copies are saved at some off-site place; you continue to avail the plugin backup and security at the little amount of $3.75/month. You need not worry about your website and its security being backup by the highly functional tool.

2. Duplicator

duplicator

While mentioning about the WordPress backup plugins, the experts surely discuss the duplicator as one of the best backup plugins. Due to worldwide popularity, the number of people is going beyond 100,0000, who have installed it across the world. The reason why this backup plugin has very popular around the globe is very simple; for example, it copies the entire website to provide you complete data you lose due to the crashing of the website. Nevertheless, it is worth mentioning here, that the person, who uses it, needs to be well trained about some technicalities of operating it. It is therefore suggested to hire a technical expert to run the plugin; instead of running it wrongly on your part. Once you hire a person to operate it or you take some training about operating it; the plugin better secures your website than the many other websites.

3. CYAN Backup

cyan-backup

It is also a very effective WordPress backup plugin to secure your website. Moreover, it happens to be providing, hourly, daily, weekly, and monthly backup as per your need. In addition to it; you can opt for backing up limited data of your choice. It is at your disposal to use it as per your needs.

4. Backup Buddy

BackupBuddy-WordPress-Plugin-Free-

Another highly effective backup plugin secures your website as per your demand. You are free to avail of its services daily, weekly basis, or monthly basis. The paid plugin entertains your all needs quite effectively. Its services keep you free of mental stress by realizing you that the data of your website has gone in safe custody; it will surely be restored if the website crashes due to any reason. It is your true buddy like its name “Backup Buddy”

5. BlogVault Real-Time Backup

blogvault

It has proved to be a very functional backup plugin keeping your website data off-site to recover easily at the time of need. The data can easily be restored once the website is crashed by a hacker or it crashes due to any other reason. The amount of money to get the service rests between $8 to $9 approximately. The biggest websites are also given backup plugin support by the “BlogVault Real-Time Backup”.

6. BackWPup – WordPress Backup Plugin

backwpup

With more than 600000 installs, the plugin has been very popular around the globe; it creates an off-site back place to keep your data more secure than it is on your website. For your information, the plugin is available online free of charges; however, it provides customized services; if you need to avail it with full resources; purchase it online for the better security of your WordPress website.

7. WordPress Backup to Dropbox

Backup WordPress Site To Dropbox For Free

The backup plugin works with the Dropbox; what you need to do to have a dropbox account to keep your data secured. Commonly, it is free of charges plugin, however, the data exceeding the limit of 2 GB can’t be secured without paying for it. To use the plugin under discussion is as easy as using dropbox.

8. BackUpWordPress

backup WordPress

Due to having a huge capacity to make a copy of every available data on your website; the backup plugin has been very popular among the users. More than 1200000 downloads are proof of its workability. You just have to install it online after paying a little amount of money.

9. UpdraftPlus

Updraft-plus

The plugin is being used across the world by more than 2 million people. The plugin copies your web’s data at the off-site place and provides you at times you need it serve any purpose; for example, your website has crashed due to any reason.

10. BoldGrid Backup

BOLD GRID

The WordPress backup plugin is highly functional making too many copies of your website to restore your website when you need it. The plugin costs $60 annually; a very little amount as compared to the benefits you gain out of it.

Conclusion

The best WordPress backup plugins have made it possible to restore your website if it crashes; the backup plugins tool performs a great service.

6-best-wordpress-giveaway-and-contest-plugins-compared-(2019)

Are you looking for the best WordPress giveaway plugins to run viral campaigns on your website?

Giveaway plugins for WordPress allow you to efficiently run a giveaway contest on your website. They allow you to maximize the incoming traffic and help you get tons of new visitors.

In this article, we will show you the best WordPress giveaway plugins to help you boost traffic, get subscribers, and improve your brand image.

Best giveaway contest plugins for WordPress

What to Look for in a WordPress Giveaway Plugin?

There are plenty of WordPress contest and giveaway plugins in the market, but not all of them have the specific features that you may need for creating a successful viral giveaway.

Some of them are good at helping you grow your email list while others are optimized to help you get more social media followers.

You need a WordPress giveaway plugin that combines the best of all features to help you increase your website traffic, grow your email list, and get more social media followers.

You also need to make sure that the plugin does not slow down your website.

Last but not least, you want to consider the costs and make sure that they are reasonable.

With that said, lets take a look at the best WordPress giveaway, contest, and sweepstakes plugin.

1. RafflePress

RafflePress

RafflePress is the best WordPress giveaway plugin on the market. It allows you to easily create highly effective viral contests and giveaways on your website.

It connects with all top email marketing platforms, so you can grow your email list.

You can also connect with popular social media platforms to get more followers and grow your website traffic from various social sharing actions.

RafflePress comes with a drag and drop giveaway builder which makes it easy to quickly build viral contests. It also has built-in templates to make the giveaway creation process even faster.

The refer-a-friend giveaway feature allows you to leverage word of mouth marketing by allowing users to share the giveaway on their social media profiles. This builds engagement and gets you tons of new visitors to your website.

RafflePress plugin also works with all WordPress form plugins, CRM Software, social networks, and lead generation software.

You also get tons of other powerful features like fraud protection, success tracking, retargeting, social logins, email verification, prize gallery, giveaway landing pages, and a whole lot more.

The giveaway works on mobile phones just as beautifully as laptops. You can also fully customize the giveaway appearance with your own images, colors, and fonts.

RafflePress has a free version available in WordPress.org directory, RafflePress lite, which you can try for free. To unlock the full power of RafflePress, you would need to purchase RafflePress Pro.

For more information, see our tutorial on how to run a giveaway / contest in WordPress with RafflePress.

Pricing: As mentioned above, RafflePress offers a free version that will help you get quick wins. However if you want all the powerful features, then the Growth plan costs $159 / year which is by far the best value compared to any other giveaway plugin in the market. For small business, their Plus plan ($39 / year) and Pro plan ($79 / year) are very well priced.

Note: WPBeginner users can get 20% discount on their purchase by using our RafflePress coupon code: WPBEGINNER20

2. Gleam

Gleam

Gleam is a popular giveaway app that works with WordPress sites. It is available as a SaaS (Software as a Service) app for website owners to create giveaway and referral marketing campaigns.

There giveaway platform is extremely robust however the user interface for setting up a giveaway is not beginner friendly. There’s a setup wizard to connect your email email service, social profiles, and select actions for qualifying entries.

Once you have created the giveaway, you’ll be given a code snippet to paste in WordPress post or page where you want to add the contest.

Gleam also creates a separate giveaway landing page on their own website that you can use to promote the contest on social media.

All your contest data is stored on the Gleam website, and there are limited export options for user data. You will also need to upgrade to the Business plan to remove their branding and logo from your campaigns.

Pricing: The Business plan costs $149 per month which is what you need to unlock most of their powerful features. While they have lower level plans such as Hobby plan ($10 per month) and Pro plan ($49 per month), they are limited in features / integrations. Their free plan is extremely limited and is not even worth mentioning.

3. Rafflecopter

Rafflecopter

Rafflecopter is a popular giveaway / sweepstakes app for all kind of websites. It is available as a SaaS app, which means you’ll need to add the giveaway widget to your WordPress site using a code snippet.

It works with all major email marketing services and offers integrations with popular social media networks. Rafflecopter also comes with refer-a-friend feature, polls and survey options.

You can easily customize the appearance of the giveaway widget with your own images and background.

Rafflecopter has a limited free plan, and you’ll need to upgrade to one of their paid plans to truly make the most out of it.

Pricing: Basic plan costs ($13 per month) which gives you few additional features. If you want email integrations, then you will need to use their Grow plan ($43 per month). The ability to remove Rafflecopter branding and the powerful refer a friend feature is only available in their Premium plan ($84 per month).

4. Simple Giveaways

Simple Giveaways

Simple Giveaways is another good option to create a giveaway on your WordPress site. It is available as a limited free version, but you will need the paid plugin to access most features.

You can create your giveaway using their simple interface. The plugin allows you to add multiple ways to submit entries for the giveaway.

It has limited entry options and allows you to integrate Facebook, Twitter, few email marketing services, and other WordPress plugins. It also includes fraud protection with Match CAPTCHA and basic tracking reports for your contest.

Pricing: The premium version starts at $49 per year for 1 site.

5. KingSumo

KingSumo

KingSumo is a premium WordPress giveaway and referral marketing plugin. It comes with a simple user interface which allows you to easily create a viral giveaway.

It includes social sharing options for Facebook, Twitter, Facebook Messenger, and Instagram. It also works with several popular email services to grow your email list.

The plugin version of KingSumo is a bit outdated, and they have a new SaaS giveaway product that’s being promoted on the website.

Pricing: The SaaS giveaway app costs $228 / year. You can get the WordPress plugin version licensed at $198 for 1 site or $594 for unlimited sites.

6. WP Contest Creators

WP Contest Creator

WP Contest Creator is another good option to add giveaway contests to your WordPress site. It allows you to connect with popular email services, and you can create different social interactions for users to earn entries.

It also allows you to automatically send emails to users when they enter the giveaway. You can utilize these emails to tell users how they can increase their chances of winning.

Optionally, you can add gamification to your contest by displaying a leaderboard of participants with the highest entry scores.

It also provides some design options, but they are not as easy to follow as other solutions mentioned in the list. The plugin’s backend is also a bit complicated and beginners may find it a bit difficult to use.

Pricing: $69 / year for a single site license.

Which is The Best Giveaway Plugin for WordPress?

All the solutions we mentioned above allow you to run giveaway contests on your WordPress site. However, they each differ in terms of features, ease of use, speed, pricing, and privacy.

We believe RafflePress to be the overall best WordPress giveaway plugin for all users. It is extremely easy to use and comes with an intuitive drag and drop builder.

It runs on your own website, so you have full control of the data and user interactions. RafflePress also comes with success tracking and retargeting features which make your campaigns even more powerful. Their pricing is also by far the most affordable in the list.

If you don’t mind adding code to your WordPress site or run your giveaway on a SaaS platform, then Gleam and Rafflecopter can be a good option, but their premium versions are very pricey.

We hope this article helped you find the best giveaway plugin for your WordPress site. You may also want to see our guide on how to get more traffic to your website with practical tips.

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.

best-wordpress-calendar-plugins-of-2019

by

Length:MediumLanguages:

WordPress calendar plugins come in many styles and have features to suit an equally wide variety of needs. Some calendars offer complex booking or scheduling features, while others are simple event management calendars. 

  • Whether you need an event calendar plugin, a booking system with payments, or a Google Calendar widget, this list of plugins will have something to improve…

  • In the digital age, users are online 24/7. Everyone prefers to check availability and make appointments, reservations, or bookings online. They want to do…

  • Build a schedule for your website, complete with Google Maps integration, call to action buttons, and a complete automated booking and ticketing system for…

  • Regardless of niche, adding a calendar plugin to your WordPress site is a great way to improve user engagement and retention. In this tutorial, I’ll show you…

Whatever your need, if you’re looking for a premium calendar plugin, this list of the ten best WordPress calendar plugins for 2019 will help you decide which one is right for you. 

1. EventOn

EventOn

EventOn is one of the best-selling WordPress calendar plugins at CodeCanyon and it’s no wonder. The calendar’s default setting shows a small photo thumbnail with event name, date, time and location. When a viewer clicks on that info in the calendar, it opens up to display more details including an embedded Google map, social media share buttons, and buttons that allow you to add the event to Google calendar or your own calendar. Users can also add future events when they’re part of a series or recurring events, like for events that occur weekly or monthly. 

If you need even more customisation, there are a number of add-ons available that will allow users to add functions like events with a countdown timer, seating selections, and ability to review the event. There’s also a FullCal add-on that adds a clean, grid-based design to the calendar to display events in a traditional calendar format, and the appearance editor allows you to customise the look of the calendar to match your website style.

User alexsieff says:

“Very good program. I love the flexibility. You can buy the basic module, which works well, and gradually according to your needs, add add-ons. Good assistance.”

2. Bookly PRO

Bookly PRO

Bookly PRO offers users an automated online booking and scheduling calendar for WordPress. This fully-customisable booking form is responsive so that it can be used seamlessly on any device. It offers online payments, notifications, and syncs with Google Calendar. Booking lists can be searched, filtered, sorted and printed or exported to CSV.

Another great feature is the two-way synchronisation between Bookly Calendar and Google Calendar which automatically reflects all updates you make in either calendar.  

You can add more advanced functions to your default configuration with a wide selection of Bookly add-ons available with your purchase.

User Mabeny says:

“Great Plugin with several features and add-ons, really easy to customize and very quick, helpful and friendly support.”

3. Calendarize it! for WordPress

Calendarize it for WordPress

Whether you need a lightweight events calendar or one with more options and features, Calendarize it! is an excellent choice. That’s because, though it offers a traditional monthly events calendar as its default option, you can expand the functions of the calendar with the wide range of free and paid add-ons on offer.  

Some examples of great free add-ons available are the Social Share Panel, Member Profile, Ratings and Reviews, and the Visual CSS Editor add-ons. Other add-ons allow users to add a number of different calendar viewing options like an Event List View, Map View and Grid View.

User DEEPERBLUE says:

“Brilliant Calendar plugin. They really bent over backwards to resolve an issue we were having. Top notch support, highly recommend to anyone looking for a calendar on their WordPress site”

4. Booked—Appointment Booking for WordPress

BookedAppointment Booking for WordPress

Booked—Appointment Booking for WordPress is a simple appointment booking calendar that allows you to create a number of calendars, each with their own time slots and custom feeds and then to assign each calendar to a specific user to manage. 

Some of the plugin’s outstanding features are guest booking which allows guest to book appointments without the need to register, custom time slots, custom appointment fields, customer ability to add events to their Google calendar, and colour customisation options.

User isntritchie says:

“Simple to use, yet complex to suit any need. A perfect combination. Support is fantastic and I cannot recommend this product high enough. I am a developer myself and everything from the interface to the performance is top tier!”

5. Timetable Responsive Schedule For WordPress

Timetable Responsive Schedule For WordPress

Timetable Responsive Schedule For WordPress is a powerful and easy-to-use WordPress event calendar plugin for users who want to create a timetable view of events in minutes and for users who want to take online reservations for an event within available free slots. These features make it an ideal plugin for solopreneurs like coaches and various kinds of teachers and tutors.

The plugin, which is also compatible with WPBakery Page Builder, comes with an integrated widget to display upcoming events in the form of a scrollable list. It is highly customisable and responsive and you can easily generate a PDF from your the timetable view if needed.

User zefstudio says:

“Great plugin! Easy to use! Modern design!”

6. WordPress Pro Event Calendar

Wordpress Pro Event Calendar

WordPress Pro Event Calendar offers an elegant and modern design, with responsive layout and easy to manage events. Some of its standout features are the ability to import events from ICS feeds and Facebook and to accept events submitted by front-end users, making it easy for users to add events. Other noteworthy features are Google Maps integration, custom fields and date range support, WPML support, ability to subscribe to a calendar, and much more. 

User datapress says:

“Great plugin and excellent support.”

7. Events Calendar Registration and Tickets

Events Calendar Registration and Tickets

Events Calendar Registration and Tickets is a great choice if you regularly run seminars, events, classes, workshops, conferences, concerts, etc. from your WordPress site and need to provide participants with a means to register or purchase tickets. 

The plugin allows you to not only manage your events, but also keep track of attendees, and sell tickets all from the admin section of your website. What’s more, the admin interface is easy to use and extensive documentation is provided to help you set up your events in no time. 

The all-in-one WordPress calendar plugin provides all the addons and features you need in an events calendar as part of the initial price, and you can rest assured that the software will be regularly updated to keep up with technological advances. 

User Han_Fei says:

“Great support, great plugin, really nice stuff… good job!”

8. Event Booking Pro

Event Booking Pro

If you’re looking for an event booking system, you need to check out Event Booking Pro. The responsive WordPress calendar plugin is loaded with useful features like offline booking, PayPal and coupon integration, support for unlimited events and more. 

There’s no shortage of shortcodes, and everything can be customised so that it integrates into your WordPress theme seamlessly. 

User Pahtreaq says:

“Great plugin that’s rather easy to work with”.

9. Events Schedule

 Events Schedule

Events Schedule is a simple WordPress calendar plugin that offers 12 unique schedule styles, each with different designs and features that can be modified with one click. Each style is suited to a different kind of business.

There are certain features that each template shares, like an elegant pop-up that provides more information about an event when you click designated areas of a calendar, the ability to assign certain details that make it easy to filter information in the calendars, and call-to-action buttons that you can insert to convince visitors to interact right away with your offer.  

User cjouper says:

“Has great template options for different ways to display calendars, depending on your content. When I needed help from tech support it was very quick and efficient. Highly recommend!”

10. HBook

HBook

HBook is a hotel booking system which is perfectly suited for anybody owning a business in the hospitality industry, be it a hotel, holiday apartment, or B&B. The booking system allows you to provide an online reservation system for your guests on your WordPress website. With it, you can add availability calendars, table rates and booking forms to your website quickly and easily. 

User emiliegrau says:

“Great customer support. Great plugin to take direct bookings from your own website. Nice integration with your own theme. You can also sync with major booking platforms.”

Choose the Best WordPress Event Calendar Plugin for You

Today we’ve looked at the ten best WordPress Event Calendars for 2019. Obviously, the one you choose will depend on your specific needs. Give one of these calendars a try and let us know what you think in the comments below. 

Meanwhile, if you’re interested in more options for calendar and booking plugins, check out the super helpful articles below. 

12-best-wordpress-donation-and-fundraising-plugins-(2019)

Are you looking for the best WordPress donation plugins?

Collecting online donations is a very effective way to raise funds for a non-profits, charities, relief funds, and special causes.

In this article, we will share the best WordPress donation and fundraising plugins that will help you easily collect one time donations as well as recurring donations using PayPal, Stripe, WooCommerce, other credit card processors, and even cryptocurrency.

Best WordPress donation plugins

How to Choose the Best WordPress Donation Plugin

There are dozens of WordPress donation plugins available in the market. The problem is that not all of them are easy to use, and a lot of them lack customization options.

Accepting donation payments on your WordPress website is an extremely important task.

You need a donation plugin that is reliable, works on mobile as well as desktop computers, supports your preferred payment gateway, sends receipts to donors, allow donors to make recurring donations, and is customizable enough to look good on your website.

On top of all that, you want a WordPress donation plugin that charges the least amount of fees. Ideally it should either be free or fixed yearly payment vs something that charges a percentage fee on all your donations.

We used the above criteria to compare the best WordPress donation plugins for non-profits and charities.

Here’s our editorial pick for the top WordPress donation and fundraising plugins.

1. GiveWP

GiveWP

GiveWP is one of the best WordPress plugins for non-profits to accept donations and raise funds for your cause.

What makes GiveWP standout and earn the top-ranked spot in our best WordPress donation plugin list is their complete set of features along with their non-profit friendly pricing model.

GiveWP makes it easy to create a custom donation form inside WordPress to easily setup one-time donations as well as recurring donation options.

You can integrate with a wide variety of payment gateways to accept credits card donation payments including Stripe, Authorize.net, PayPal, 2Checkout, Braintree, Mollie, Paytm, PayFast, Square, AmeriCloud, Paymill, and many more.

GiveWP also allows you to fine-tune just about every aspect of your donation process with features like customizable donation tributes like “in honor of”, multi-level donations, campaign level donation goals / incentives, currency switcher options, tax deductible donation receipts, and more.

It comes with a complete donor management area with full-featured reporting, so you can easily manage all your donations (both online and offline donations).

GiveWP integrates with all major email marketing services, so you can easily communicate with your donors about seasonal gift giving campaigns.

If you run an online store with WooCommerce, then GiveWP allows you to add a donation upsell on the checkout screen, and they have seamless Google Analytics integration with enhanced eCommerce tracking.

GiveWP’s offers a free WordPress donation plugin, but you will have to upgrade to their yearly paid plans to unlock all the powerful addons and features. Basic paid plan starts at $240 / year, but you will need the Plus plan ($360 / yr) to get all their add-ons.

2. WPForms

WPForms

WPForms is the most beginner friendly drag & drop form builder for WordPress. It comes with a built-in form template to create an online donation form on your website.

A lot of smaller charities and non-profits don’t need a full-featured giveaway platform. Instead they just want a simple and easy to customize donation form that can accept one-time and recurring donations.

WPForms offer you just that. It integrates with both PayPal and Stripe, so you can securely collect donations via credit card right on your website.

Since WPForms is a more comprehensive form builder, it can also serve multiple purposes for a charity website such as contact form, survey forms, polls, email newsletter signup form, volunteer signup form, etc.

WPForms seamlessly integrates with all major email marketing services and CRM platforms like Constant Contact, SendinBlue, AWeber, MailChimp, and hundred others.

WPForms free plugin is used by over 2 million websites, but you will need their payment addons to accept online donations. They offer a special discounted license for non-profits at only $99 / year which is 75% off their regular price.

This gives you all of their Pro features that lets you build donation forms as well as other types of forms that we mentioned above. You can see the full list of over 150 form template demos here.

Note: WPForms is a sister company of WPBeginner. The plugin was co-created by WPBeginner’s founder, Syed Balkhi.

3. Easy PayPal Donation

PayPal Donation for WordPress

Easy PayPal Donation is a free WordPress donation plugin that lets you add a PayPal donate button on your website.

Your website visitors can click on the button and send donations using their PayPal account or credit card.

This is a very simple donation plugin that comes with 7 button templates, and you also have the option to upload a custom button style to match your design.

The goal of this plugin is to make it easy to connect your PayPal account with WordPress and receive the donations. This plugin also allows visitors to choose recurring monthly donation options.

We have this plugin listed as #3 not because it’s the most feature-rich, but because sometimes you may not need all the features that plugins GiveWP and WPForms offer.

If you don’t want to customize your donation form and want a straight-forward solution that’s completely free for accepting one-time donations, then this plugin can do the job for you.

For setting up recurring donations, you will need their Pro version which costs $59.95 / year at which point you’re better off going with WPForms because you get a lot more value.

4. WP Crowdfunding

WP Crowdfunding by Themeum

WP Crowdfunding is a powerful WordPress fundraising plugin that helps you create a fundraising backer site like GoFundMe or KickStarter.

You can use the crowdfunding campaign style only for your charities or even offer an aggregate fundraising platform for other charities in your network.

It integrates with Stripe, PayPal, Authorize.net, and all WooCommerce gateways if you choose to process your payments with WooCommerce. WP Crowdfunding Native wallet system allows you to track pledges for each campaign and distribute funds accordingly to individual stakeholders.

If you’re looking to create an aggregate crowdfunding site like GoFundMe, then you also have the option to charge a commission fee for helping other charities collect donations.

The base plugin is free, but you will need to upgrade to the paid plan to unlock full features which starts at $149 / year.

5. Charitable

Charitable

Charitable is an easy WordPress donation plugin that allows you to create unlimited fundraising campaigns and set goals for your cause.

You can select a fixed donation amount, add a custom amount, or both. You can embed the donation form on your pages, posts, sidebars, and modal popups.

While the base plugin is free, you do have to upgrade to their Plus plan ($99 / year) to unlock their payment gateways like Stripe, Authorize.net, etc as well as newsletter sign up forms.

If you want recurring donations, crowdfunding, peer to peer fundraising, donor fee relief, and other powerful features, then you will need their Pro plan which costs $249 / year.

6. Seamless Donations

Seamless Donations

Seamless Donations is a free donations plugin for WordPress. It gives you complete control to collect and manage donations within the WordPress dashboard.

Seamless Donation works with PayPal, so users can make donations using their PayPal account or credit cards.

You can accept one-time donations or recurring donation payments. You can also allow users to select which campaign they want their funds allocated.

Unlike other plugins, Seamless donation sells few addons on an a-la carte basis such as Thank You Enhanced which lets you setup custom thank you pages and Giving Level Manager which lets you attribute custom donation levels.

7. Donorbox

Donorbox

Donorbox is a powerful donation form plugin that works on both WordPress as well as standalone websites.

It allows you to setup one time donations as well as monthly, annual, and weekly recurring donations. You have the option to do company gift matching and accept company donations.

Donorbox allows you to accept payments from credit cards as well as popular payment platforms like Apple Pay, Google Pay, PayPal Express with One-Touch, and ACH bank payments for US and Europe based donors.

It also comes with many other powerful features like Goal Meter, Donation popup forms, multi-currency support, donor wall, donor profile, complete donor management, end of year tax receipts, and so much more.

The reason why we have Donorbox listed towards the bottom in our list is because their pricing is not friendly to non-profits.

While they let you collect free donations for up to $1,000 per month, you will have to pay a 1.5% platform fee for all other amounts. This platform processing fee is in addition to the payment processing fees that are added by Stripe, PayPal, and other banks.

They do have the option to have your donors cover the fees, but we believe its better to use a platform like GiveWP where more of the donation money goes towards the actual cause.

Donorbox also charges separate monthly fees for various email marketing and CRM integrations.

To be fair, out of other SaaS donation platforms like Crowdrise, Donately, etc, Donorbox is by far the most affordable.

The reason why you may want to use the Donorbox platform is because they take away the technical management headache away from you.

You don’t have to worry about the security of your payment infrastructure because it’s all handled by their team.

8. Formidable Forms

Formidable Forms

Formidable Forms is the most advanced WordPress forms plugin. It allows you to easily create complex forms with drag and drop builder.

It has tons of form templates including a pre-built template to collect online donations. You can view the donation stats in graphical charts within the WordPress dashboard.

The plugin allows you to export the form data outside WordPress. It also gives you the option to import your donation entries from third-party services. Formidable Forms is fully compatible with the WPML translation plugin to translate the form in any language.

9. Donation Thermometer

Donation Thermometer

Donation Thermometer is a classic WordPress donation plugin. It uses a thermometer style parameter to display the collected funds and your target amount.

It is ideal for sharing your fundraising campaign with your website visitors and motivate them to help out. It is also perfect for organizers to see how close or far away they are from their fundraising target

The thermometer is fully customizable for colors, text, currency, meter size, and more. You can use a shortcode to display the donation thermometer in your posts and pages. All settings are easy and manageable within WordPress.

It’s important to note that this plugin DOES NOT help you accept any donations. You can use it alongside any of the other WordPress donation plugins in this article.

10. PayPal Donations

PayPal Donations

PayPal Donations is another free WordPress PayPal donation plugin to raise funds for charities and non-profits. You can use their sidebar widget or the shortcode to add the PayPal donation button on your website.

Like other PayPal plugins, it lets you connect WordPress to your PayPal account and accept donations from visitors. Other settings include multiple currencies, localization, multiple button sizes, and more.

11. YITH Donations for WooCommerce

YITH Donations for WooCommerce

YITH Donations for WooCommerce allows you to add an option to collect donation in your online stores.

You can run seasonable campaigns to support your causes. Each time a user adds a product to cart, they will be prompted with an option to make a small donation.

This concept is utilized by many in the retail world, and YITH Donations for WooCommerce allows you to add this to your eCommerce website.

YITH has a free version of the plugin that’s quite limited. To get all the features like donation form on cart page, customize amounts, donation receipts, etc, you will need the premium version of the plugin which costs $59.99 for a single site.

Note: GiveWP also offers this feature along with a lot more which we believe is a better value.

12. Cryptocurrency Donation Box

Cryptocurrency Donation Box – Bitcoin & Crypto Donations

If you’re looking to accept donations in cryptocurrency, then look no further. This free WordPress donation plugin allows you to accept donations in top 20 major cryptocurrencies.

You can accept payments in Bitcoin, Ethereum, Bitcoin Cash, Litecoin, Cardano and more.

Which is the Best WordPress Donation Plugin?

The plugins we mentioned in this article can all help you collect donations on your WordPress. However deciding the best WordPress donation plugin for your online fundraising will vary based on your needs.

If you’re looking to create a simple donation form with one-time and recurring donation option along with the ability for users to make payments via PayPal or credit card, then WPForms non-profit plan is the best value because they’re offering 75% off discount.

If you want a WordPress donation plugin that comes with advanced features like complete donor management, tax deductible donation receipts, campaign level goals / incentives, multi-level donations, customizable donation tributes like “in honor or”, full-featured reporting, a wide-variety of payment platform integrations, then nothing in the market beats GiveWP, and that’s why GiveWP is our pick for the #1 best WordPress donation plugin.

We hope this article helped you find the best WordPress donation and fundraising plugins for charities and non-profits. You may also want to check out our expert pick of the best WordPress page builders and must have WordPress plugins for all sites..

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.