Archive

Archive for May, 2015

Designing For Explicit Choice

May 25th, 2015 No comments
03-moissanite-opt

If you’re a UX designer, you’ve probably designed a lot of forms and web (or app) pages in which the user needs to choose between options. And as a designer, you’re likely familiar with best practices for designing forms. Certainly, much has been written and discussed about this topic. So, you probably know all about how best to label and position form fields and so on for optimal usability.

But have you thought about how the design of a form affects the user’s decision-making? Have you ever considered to what extent the design itself affects the choices people make? As always in design, there are a variety of ways to design a form or web page.

For example, let’s say you’re designing a system in which the user needs to indicate whether they would like to sign up for a particular preventive medical procedure, like a flu shot. You could design the form in a number of ways. For example, you could provide a checkbox where the user either opts in or out. Alternatively, you could design it so that the user is required to explicitly choose between two options (via radio buttons).

Examples of these two approaches are shown below:

Would it matter which way you design it? Would the user make the same choice regardless of which design they encounter? Or could the user potentially be led to make a different choice merely as a result of how the choice is presented or designed?

The Power Of Defaults

One key difference between these two designs is that the checkbox requires a default state. That is, upon display, the checkbox will appear either checked or unchecked, as opposed to the radio buttons, which do not require a default selection. In the second example, even if the user does nothing, a “choice” has already been made, via the default.

A robust body of research1 has shown that when a default choice is offered, most people do not deviate from it. For example, if the box is checked by default, many don’t uncheck it (and vice versa). Making an explicit decision requires effort, after all. Time, thought and consideration are often required to determine the best choice. It turns out that people are remarkably sensitive (and averse) to the amount of effort that making a choice demands.

People are also remarkably sensitive to any possibility of incurring a “loss” that might then subsequently trigger feelings of regret. Especially when one is unsure how to choose, not making a choice (by simply accepting the default) feels better than actively making a choice that might end up being the “wrong” choice. Because people often have an unrealistic expectation that they will have more time in the future to make a more informed decision, procrastination also works2 in favor of acceptance of the default. Deviating from the default requires an explicit action, which people delay in taking. In many ways, defaults make decisions feel easier and less risky.

Designing For An Explicit Choice

The judicious use of defaults, then, has proven to be a key driver in the choices that people ultimately end up with, in large part because many people simply go with the default option. But one problem with passive decision-making3 is that it’s less likely to engender the kind of committed follow-up that is often essential to implementation of the decision, such as in the earlier example of the flu shot. Wouldn’t those who actively decide to opt for a flu shot be more apt to actually get one than those who passively accept the default?

Might there be a way to design for explicit decision-making that encourages people to feel better about actively making a choice? With this question in mind, researchers conducted a study to test how the design for an explicit choice might affect decision outcomes. Specifically, they were interested in comparing the outcomes of two approaches to obtaining an explicit choice from users regarding enrollment in a 401(k) plan (an employer-sponsored retirement plan), as shown below.

Example 1 provides two options:

  • “I want to enroll in a 401(k) plan.”
  • “I don’t want to enroll in a 401(k) plan.”

Example 2 also provides two options:

  • “I want to enroll in a 401(k) plan and take advantage of the employer match.”
  • “I don’t want to enroll in a 401(k) plan and don’t want to take advantage of the employer match.”

Would actual choice outcomes be influenced by which design users interacted with? In example 1, the two choices are weighted equally. That is, if the user doesn’t have a specific or compelling reason to choose one over the other, chances are that they may feel conflicted about which one to choose. Neither necessarily feels better or worse than the other. Example 2, on the other hand, is explicit about what the user will potentially gain or give up as a result of choosing an option.

Results of the research study4 show that enrollment in a program increased when options were “enhanced” with explicit mention of the implications of each choice, and levels of commitment and participation in the program also increased. But why would the wording of example 2 make such a difference in people’s choice? From a design perspective, stating what seems obvious about the implications of each option might seem unnecessary.

But it turns out that, because people are generally unlikely to seek out information to inform their decision, the additional wording makes a difference. Proactively seeking out information is work, after all, and research consistently reveals people’s considerable sensitivity to and avoidance of almost any amount of effort. Because of this, providing information within the options themselves can have a powerful impact on decision outcomes.

Aversion To Potential Loss

For many people who are not enrolled in a 401(k) plan, maintaining the status quo of being unenrolled doesn’t seem to incur any negative emotion, risk or “loss.” Life seems to roll on normally when one is not enrolled. Most people are aware, however, that participation in a 401(k) plan involves regular contributions to the plan — money that is no longer available for daily household expenses or other regular uses. And inherent to the act of investing is the potential for market downturns and losses incurred over the course of an investment. For these reasons, taking the step of enrolling in the plan (and potentially losing one’s investment) might feel a lot riskier than maintaining the status quo by not enrolling.

But when the costs associated with maintaining the status quo (for example, by remaining unenrolled in the plan) are made apparent and are framed as a loss (for example, loss of the employer match), then the decision to enroll in the plan feels more compelling and motivating. People are much more motivated by ways to avoid loss than to realize gains.

Consider what might happen if example 2 were framed differently:

  • “I want to enroll in a 401(k) plan.”
  • “I don’t want to enroll in a 401(k) plan and don’t want to take advantage of the employer match.”

Framing the options in this way does not remind users that they have something to gain by enrolling, only that they have something to lose by not enrolling. I suspect that users would still feel strongly motivated to enroll, simply because people give disproportionately greater weight to loss than to gain.

Real-World Examples

Research has demonstrated the power of design in enhancing explicit choices, but what about examples from the real world? One example we can look to is the US pharmaceutical company CVS/caremark5, which enjoyed greater rates of enrollment for its automatic prescription-refilling program when users were required to choose between two options:

  • “I prefer to order my own refills.”
  • “I want to enroll in the ReadyFill@Mail (automatic prescription refill program).”

The first option reminds users that not enrolling for the auto-refill program incurs a cost — the cost of having to do the work of ordering one’s own refills. It turns out that 21.9% of users decided to enroll in the program with this design of explicit choices, compared to only 12.3% of those who encountered an opt-in design. And customers who encountered the explicit choice also ended up filling more prescriptions than those in the opt-in design. It seems that preference for the program was actually enhanced once people made a commitment to joining.

Examples From The Retail World

Enhanced explicit choice is effective because it reminds people what they will gain or lose as a result of making a certain choice. Some online shopping websites are leveraging the power of such “reminders.”

Moissanite6 is one such example. After a short time on its website, the user is presented with a modal requesting their email address in exchange for a 10% discount on their next purchase. Providing one’s email address, of course, incurs the “cost” of potentially getting unwanted email, etc. But at the bottom of the modal is a reminder of the cost of not signing up: “No thanks, I prefer paying full price.” Paying full price, of course, implies loss because the user could instead be enjoying a discounted price.

7

Consider another example, Bauble Box8, which takes this concept a step further. After a short time on the website, the user is presented with the following modal, offering a 15% discount on one’s first purchase in exchange for an email address.

02-baublebox-opt9

Noteworthy is the fact that there is no obvious way to close this box — for example, no “X” or “Close” (which would normally be located in the upper-right corner). To dismiss the box, the user must click the “Continue as guest” link towards the bottom of the box. And it might not be immediately apparent that this is a link.

The design seems to leverage these usability issues by forcing the user to hunt around for a way to dismiss the box, until they finally discover the “Continue as guest” link. Although this design risks user frustration, it nevertheless forces more time and attention towards the content of the box than users would ordinarily spend, increasing the likelihood that they will also notice the parenthetical text under the link, “(Without my 15% off coupon!)”

This design raises some interesting questions about how users perceive the experience and, consequently, whether this is a website they want to give their business to. To what extent might user frustration with the (intentional) usability issues adversely affect their perception of the company and the brand? At what point does the design cross the line to the dark side? These are important considerations, especially for companies that want to establish long-term relationships with their customers built on trust and delight.

Final Thoughts

We’ve covered a lot of ground in this article. We’ve seen that defaults are powerful because they provide a way for users to passively decide, thereby easing the difficulty and effort associated with decision-making. But we also know that, for a variety of reasons, providing a default option is not always appropriate. Sometimes, it’s better for users to make an explicit choice — especially when they are more likely to follow through with a decision and be more committed to taking action on it.

A primary lesson from this article is that merely reminding people what they stand to gain or lose as a result of making a particular choice can have a powerful impact on how they choose. And depending on the type of decision, how they choose can have significant implications for their lives. We’ve seen, too, that designing for explicit choice can manifest itself in different ways, depending on the subject matter and context of the experience.

It’s imperative to understand that the design matters. UX design professionals have a responsibility to understand how design itself influences — and sometimes even drives — user perception and behavior and, therefore, decision outcomes. To this end, the decisions we make as designers matter.

(cc, al, il)

Front page image credits: Innovative Techniques To Simplify Sign-Ups and Log-Ins10.

Footnotes

  1. 1 http://www.hks.harvard.edu/fs/rzeckhau/SQBDM.pdf
  2. 2 http://people.duke.edu/~dandan/Papers/PI/deadlines.pdf
  3. 3 http://psp.sagepub.com/content/22/2/133.short
  4. 4 http://www.cmu.edu/dietrich/sds/docs/loewenstein/EnhancedActiveChoice.pdf
  5. 5 https://www.caremark.com/wps/portal
  6. 6 http://www.moissanite.com/
  7. 7 http://www.moissanite.com/
  8. 8 http://baublebox.com/
  9. 9 http://baublebox.com/
  10. 10 http://www.smashingmagazine.com/2011/05/05/innovative-techniques-to-simplify-signups-and-logins/

The post Designing For Explicit Choice appeared first on Smashing Magazine.

Categories: Others Tags:

20 Fresh and Free WordPress Themes: May 2015

May 25th, 2015 No comments

I know I am a junkie. I can’t get enough of WordPress themes! And I know it’s the same with lots of you, so I went to every corner of the web looking for the coolest themes for your websites. There’s one for pretty much any kind of website – photography, e-commerce, super minimal design, and more. So go ahead and give your WordPress blog a fresh new look. May the May be with you… All these themes are free though some have commercial variants available. We stated that where applicable. Enjoy! Shopper Created by/for: Dessign Features: eCommerce oriented, super minimal grid layout, needs a few plugins to work at its full potential License: free for personal and commercial use (GPL) BiancaA Created by/for: Theme Junkie Features: mobile-ready, great for photo-blogging, quiet minimal design License: free for personal and commercial use (GPL) Stacker Lite Created by/for: Theme Furnace Features: grid-based, social links menu, custom colors and columns License: free for personal and commercial use (GPL) Sensible WP Created by/for: Modern Themes Features: suited for any type of website, fully customizable, subtle animations License: free for personal and commercial use (GPL) Hew Created by/for: Automattic Features: prominent […]

Categories: Others Tags:

Fair Pay for Authors: Post Pay Counter for WordPress

May 24th, 2015 No comments

Need a solution to pay authors on a WordPress multi-author blog by certain criteria? The Post Pay Counter plugin might be what you’re looking for. This plugin allows the administrator of a multi-author website to customize the basic configuration and choose from various payment options. There’s a free and a PRO version, which I’d like to introduce to you today. The Post Pay Counter WordPress Plugin The basic idea behind this plugin is to provide fair payment for the authors of a website. It also simplifies the calculation. The admin can specify criteria upon which payments should be processed. Stats can be viewed immediately for all authors or only one author. This plugin helps you setting up a revenue sharing model where authors can be paid per post. And Here Is What the Post Pay Counter Plugin Can Do You decide if you want to pay your authors per post, words, images, or page views. Or go for an incremental payment system. If your author charges, for example, $0.05/word, this would make $5/100 words. A registration is not required; your data remain safe on your server. Post Pay Counter is not a cloud service and therefore doesn’t require a user […]

Categories: Others Tags:

Online Marketing Basics #6: Introduction to Email Marketing

May 23rd, 2015 No comments

The sixth part of our series on Online Marketing Basics deals with email marketing. We will discuss its main aspects and how to do it. Furthermore, we explain some regional legal aspects that come in handy if you want to do a campaign in Europe. Email marketing is by definition very appealing – after all, this marketing tool gets you right into the inbox of your prospective target group. Mailing lists are a treasured asset in online marketing. They allow you to directly reach out to your potential customers. That’s why email marketing promises high conversion rates. This is only true, though if people shared their data deliberately and if they are part of your target group at all. If not, you might not only face insufficient conversion rates but, in the worst case scenario, even legal challenges. Learn About 3 Kinds of Email Marketing Newsletter: Newsletters are emails that are regularly sent to subscribers. They contain useful information and news, or plain commercial content, or a mixture of both. For newsletters to be successful they have to be sent at least every two months, but not more often than once a week. Of course, they ought to be appealing […]

Categories: Others Tags:

Rekindling Your Passion For Web Design

May 22nd, 2015 No comments
An incredible amount of sharing, learning and networking can happen at a conference.

I love being a web designer and I’m incredibly thankful that I decided to join this industry many years ago. Still, despite my love of this profession, there have been a number of times during my career when my passion has waned and I’ve found myself simply going through the motions instead of fully applying myself to my work. This scenario is likely familiar to many of my fellow web designers. It is called burnout.

Burnout is a very real challenge that we face as web professionals. The same processes that help us complete projects successfully can also contribute to us falling into a routine and hitting autopilot on our work. Sometimes, an overload of work can force you to fall into a routine and become a production line in order to meet deadlines. Other times, a lack of variety and excitement can lead to apathy with burnout not far behind.

Whenever I have started to experience burnout in my career, thankfully I have recognized the situation and been able to work to resolve the problem. In this article, I will share some of what I have found helpful in rekindling my passion for web design.

Talk To Your Peers

If anyone can understand your feelings of burnout, it is fellow web professionals. They have likely experienced something very similar and they may be able to give you advice on how to handle the situation. Sometimes, simply talking to others is the catalyst you need to break out of a funk and get excited about your work again.

Attending a web conference is one of the best ways to meet and interact with other web professionals. Listening to presentations from some of our industry’s best and brightest, and then being able to discuss that content with fellow attendees at lunch or at an after-conference party, always gets my creative energies flowing. I have never returned to the office after a conference and not been full of fresh ideas and excited to get back to work! Of course, conferences do not happen all the time, nor are they inexpensive to attend.

1
An incredible amount of sharing, learning and networking can happen at a conference. (Image credit2)

If you cannot go to a conference for one reason or another, then local meet-ups are another way you can connect with your peers. If there are no groups that meet currently in your area (you can check a site like meetup.com3 to find some events near you) then consider organizing a new group by reaching out to some other designers or agencies, choosing a time and place to meet, and starting a meet-up group yourself.

Take A Break

There’s a reason why companies give their employees vacation time – because time away from the office is an important part of maintaining a healthy work/life balance. This point is something I covered in a previous article I wrote here on Smashing Magazine about fostering healthy non-professional relationships4. Still, while vacations are indeed important, sometimes one week away from work is not enough.

I remember speaking with a web designer I had collaborated with on a few projects about a sabbatical that he took a while back. He had felt himself burning out and decided that he wanted to take six months totally away from his job. Now, few of us can just walk away from our work for half a year, but he planned it out and made preparations so that he could make it happen. He looked hard at his budget and made some changes so he could save some money and give himself a cushion that would allow him to go without any income during his time off. He admitted to me that it was difficult, but workable, and he did take that time off after about a year of working and saving.

During his sabbatical, he surfed, he read books (not ones about web design), took a cooking class, and, above all, he stayed away from work. No checking emails or calling into the office. He truly took time away, and he said that it was wonderful – not only the time during this sabbatical, but also the moment when he returned to work. He was full of new ideas, refreshed and invigorated. He also reported to me that he had a new outlook on his work and on potential burnout. Having taken the steps to make his sabbatical happen, he now knew that should he ever hit that wall of burnout again, he could find a way to take some significant time off to get back on track.

If you are experiencing burnout, be sure to use your vacation time effectively. If that time is not enough, consider taking a more significant break. It may not be easy to manage, but with some proper planning, you can find a way to make it work.

Teach Others

About six years ago, I began teaching website design and front-end development at my state university. When I took the position, I thought that it would be a refreshing change of pace that would allow me to share my knowledge and experience in a whole new way. The reality of what I got out of the experience far exceeded my expectations going in.

For me, teaching helped me remember the energy I had when I first started in this industry. It’s easy to let the weight of project deadlines, client problems, and the day-to-day challenges of the job drown the sense of enthusiasm and excitement you had when you were working on websites in the early days of your career. I see that energy in my students and it is infectious. You can’t help but have it seep back into your work as well!

5
Trends in the industry are constantly changing. By teaching, you can continuously learn and catch up with these new trends. (Image credit6)

If you cannot find a position teaching at a school, you can still be a mentor to new web professionals. Consider adding an internship program at your company and allow those web designers just entering the industry to benefit from your years of experience, while you benefit from their enthusiasm for their newly chosen profession!

Take On A Passion Project

Few of us in the web industry truly get to choose the projects that we work on. If you work for an agency, you have to work on the projects that the agency closes and which are assigned to you. If you are an in-house resource, you work on the projects that your company needs completed. Even if you run your own company, you still have bills to pay and, sometimes, you take the projects that you have to – and it is not always the work that you’d like to be doing.

My first job in the web industry was working for a company that made websites for small real estate companies. That is all we did. Day in and day out, I worked on real estate sites. As you can imagine, it became pretty monotonous pretty quickly.

Around this same time, I began playing in a band7 with some long-time friends of mine. Since I knew how to build websites, I became the band’s “webmaster” by default. The work that I was able to do for the band’s site, a project that I was obviously personally invested in and passionate about, gave me an outlet for my creativity that my normal work didn’t provide me at that time. It kept me passionate and interested in my profession.

Do Some Good

While projects you have a personal attachment to can absolutely help rekindle your passion for web design, so can working on projects that help make a real, positive difference in people’s lives. Putting your skills to use in the service of a non-profit organization is a wonderful way to do this.

Think about the charitable organizations in your area that could use some web design assistance. While large, well-established (and well-funded) charities likely have marketing teams and budgets, smaller organizations, like animal shelters or church groups, probably do not. Those are groups where your work can really make a difference and where you can apply your passion for your profession to affect positive change in your community.

Try to avoid routine work and find new perspectives every now and then. Try not to think of the obvious things, but instead think of the things beyond them.8
Try to avoid routine work and find new perspectives every now and then. Try not to think of the obvious things, but instead think of the things beyond them. (Image credit9)

Embark On A New Challenge

A number of years ago, I was working for a company that produced touchscreen kiosk systems. I liked the people I worked with and the work that I was doing, but after close to six years on the job, I had to admit that I was not doing my best work. Projects had become routine and I was just returning to comfortable solutions that had worked for me in the past, instead of trying to innovate and grow. I needed a change, and I realized that the only way I could achieve that change was by leaving the company.

This was not an easy decision. As I said, I liked the job and had been there for some time, but it was the right decision. As I thought about it, I was indeed scared, but I was also excited. That excitement was something I had not felt in some time. It felt great and it made me realize I was on the right path.

In the end, I joined a new company that provided me with a wealth of new challenges, including the opportunity to grow and continue to challenge myself in the future. Making this type of change in your career may not be easy – it certainly wasn’t for me – but if you want to rekindle your passion for your work, this kind of drastic change may be exactly what you need.

Is Passion Necessary?

So far, we’ve spent this entire article looking at ways you can bring passion back into your web design work, but we should also ask the question: is passion actually necessary in your work?

The answer to this is an individual one. You need to decide for yourself whether or not passion is an important part of your career needs. For some people, passion simply isn’t that important. I think about my parents, two people who had long and successful careers as a health inspector and a medical transcriptionist. They both enjoyed their jobs and they worked hard, but they certainly weren’t passionate about what they did. They didn’t spend nights and weekends reading up on the latest developments in their field or honing their craft. They liked their jobs, but that is as far as it went, and that was fine for them. For myself, however, that is not what I want out of my career.

Ask yourself whether passion is really necessary in your work. Be honest.10
Ask yourself whether passion is really necessary in your work. Be honest. (Image credit11)

For me, passion is, indeed, important. If you feel the same, but have seen that passion slipping lately, hopefully the ideas presented in this article will help you rekindle your excitement for your work.

How Do Your Keep The Passion In Your Work?

How about you? Do find passion for your work an important part of your career? If so, what have you found to be helpful in keeping that passion for your job intact? Share your methods and ideas in the comments section below.

(il, og)

Footnotes

  1. 1 https://www.flickr.com/photos/marcthiele/14442484671/in/album-72157644792424680/
  2. 2 https://www.flickr.com/photos/marcthiele/14442484671/in/album-72157644792424680/
  3. 3 http://www.meetup.com/
  4. 4 http://www.smashingmagazine.com/2014/05/05/fostering-healthy-non-professional-relationships/
  5. 5 https://www.flickr.com/photos/opensourceway/5538035618
  6. 6 https://www.flickr.com/photos/opensourceway/5538035618
  7. 7 http://www.smashingmagazine.com/2015/03/06/how-being-in-a-band-taught-me-to-be-a-better-web-designer/
  8. 8 http://www.flickr.com/photos/opensourceway/8250688924/
  9. 9 http://www.flickr.com/photos/opensourceway/8250688924/
  10. 10 https://www.flickr.com/photos/opensourceway/4862920379/
  11. 11 https://www.flickr.com/photos/opensourceway/4862920379/

The post Rekindling Your Passion For Web Design appeared first on Smashing Magazine.

Categories: Others Tags:

Stitches: Free CSS Sprite Generator

May 22nd, 2015 No comments

As we know, less files to download mean better loading performance and page reproduction. Therefore, icons and other images, particularly small images, are often combined into a sprite. A sprite is a collection of several images put into one image file. Creating a sprite manually requires some work. The images are arranged in an image file and their position, width, and height need to be defined in a stylesheet. The Stitches sprite generator speeds up these processes immensely. Upload Simple Images There’s probably no easier way to create sprites than with Stitches. Images you want to combine into a sprite file can be uploaded through a web interface. It supports JPG, PNG, and GIF format. Once uploaded, the images are automatically placed on a work space. You can determine if you want the images to be arranged as a compact block, next to each other, or one below the other. You can also adjust the space between the individual images. Each image requires a distinct name, so that it can be assigned to an HTML element later on. In addition, a prefix is added to the sprite preceding all classes that will be generated. Once all image files are uploaded and […]

Categories: Others Tags:

JavaScript: Using Closure Space to Create Real Private Members

May 21st, 2015 No comments

I recently developed Angular Cloud Data Connector, which enables Angular developers to use cloud data, specifically Azure mobile service, using web standards like indexed DB. I was trying to create a way for JavaScript developers to embed private members into an object. My technique for this specific case is to use what I call “closure space”. In this tutorial, I want to share with you how to use this for your own projects and how performance and memory are impacted for the major browsers. But before diving into it, let me share why you may need private members, as well as an alternate way to “simulate” private members. Why Use Private Members? When you create an object using JavaScript, you can define value members. If you want to control read/write access on them, you need accessors that can be defined like this: 1 2 3 4 5 6 7 8 9 10 11 var entity = {}; entity._property = “hello world”; Object.defineProperty(entity, “property”, { get: function () { return this._property; }, set: function (value) { this._property = value; }, enumerable: true, configurable: true }); Doing this, you have full control over read and write operations. The problem is that […]

Categories: Others Tags:

Building An Advanced Notification System For WordPress

May 20th, 2015 No comments
Subscribe 2 settings page

A lot of tools enable us to distribute a website’s content, but when we need to promptly reach a target group, an email notification system might be the best option. If your website is not frequently updated, you could notify all subscribers each time a post is published. However, if it’s updated frequently or it covers several topics, you could filter subscribers before mailing them.

If you opt for the latter, you could set up a user meta field that stores a bit of information to identify the subscribers to be notified. The same bit of information would label the posts you’re publishing. Depending on the website’s architecture, you could store the meta data in a category, a tag, a custom taxonomy or a custom field. In this article we’ll show you how to let your website’s subscribers decide when they want notifications, and linked to a particular location.

Can I Use A Plugin?

If WordPress is your CMS, you can choose from a number of plugins, such as the comprehensive JetPack1 or the more specialized Subscribe 22.

3
Subscribe 2’s settings page. (View large version4)

Jetpack is easy to use, whereas Subscribe 2 is specialized and full-featured. Both plugins enable you to send email notifications to subscribers whenever a post is published. Unfortunately, neither allows you to notify specific users about specific content. And we want to select posts based on custom fields, mailing them to specific groups of users. Unfortunately, no plugin seems able to help us with this.

Things To Do

We are going to add several functionalities to WordPress’ core, and the CMS allows us to declare our own custom functions in the main file of a plugin. We’re not going to dive deep into plugin development, but you can get the information you need directly from the Codex5.

We have to accomplish the following tasks:

  1. add two meta fields to the user’s profile, the first of which stores the name of a location and the second of which determines whether the user will receive emails;
  2. add a custom meta box to the post-editing page containing the location-related custom field;
  3. select the users to be notified and send an email to them.

Add Meta Fields To User Profiles

WordPress stores user data in the wp_users and wp_usermeta tables.

WordPress’ database description. (Image: Codex6)

Here, wp_users holds the list of all website users, while wp_usermeta contains all meta data associated with each user’s profile. Meta data is registered as key-value pairs in the meta_key and meta_value fields.

WordPress generates a bunch of meta data, such as nickname, first_name, last_name, description and wp_capabilities. Much of this data is automatically assigned to each user’s profile, and a user is able to edit it later from their profile page.

To perform our first task, we’ll add two meta fields to the profile pages of users. These fields will store the name of a geographic location and will allow the user to activate (or deactivate) the notification feature.

In the main file of the plugin, let’s define a global associative array whose elements consist of the names of US states:

$smashing_notification_states = array( 'AL' => 'Alabama', 'AK' => 'Alaska', 'AZ' => 'Arizona', 'AR' => 'Arkansas', 'CA' => 'California', 'CO' => 'Colorado', 'CT' => 'Connecticut', 'DE' => 'Delaware', 'FL' => 'Florida', 'GA' => 'Georgia', 'HI' => 'Hawaii', 'ID' => 'Idaho', 'IL' => 'Illinois', 'IN' => 'Indiana', 'IA' => 'Iowa', 'KS' => 'Kansas', 'KY' => 'Kentucky', 'LA' => 'Louisiana', 'ME' => 'Maine', 'MD' => 'Maryland', 'MA' => 'Massachusetts', 'MI' => 'Michigan', 'MN' => 'Minnesota', 'MS' => 'Mississippi', 'MO' => 'Missouri', 'MT' => 'Montana', 'NE' => 'Nebraska', 'NV' => 'Nevada', 'NH' => 'New Hampshire', 'NJ' => 'New Jersey', 'NM' => 'New Mexico', 'NY' => 'New York', 'NC' => 'North Carolina', 'ND' => 'North Dakota', 'OH' => 'Ohio', 'OK' => 'Oklahoma', 'OR' => 'Oregon', 'PA' => 'Pennsylvania', 'RI' => 'Rhode Island', 'SC' => 'South Carolina', 'SD' => 'South Dakota', 'TN' => 'Tennessee', 'TX' => 'Texas', 'UT' => 'Utah', 'VT' => 'Vermont', 'VA' => 'Virginia', 'WA' => 'Washington', 'WV' => 'West Virginia', 'WI' => 'Wisconsin', 'WY' => 'Wyoming' );

Thanks to this array, we will generate a select menu to avoid input errors by users. Now, we need to add two form fields to the user’s profile page. To do this, we will use two action hooks:

add_action( 'show_user_profile', 'smashing_show_user_meta_fields' );
add_action( 'edit_user_profile', 'smashing_show_user_meta_fields' );

Here, show_user_profile7 is triggered when a user is viewing their own profile, while edit_user_profile8 is triggered when a user is viewing another user’s profile.

The callback function prints the markup.

/**
 * Show custom user profile fields.
 *
 * @param obj $user The user object.
 */
function smashing_show_user_meta_fields( $user ) { 
    global $smashing_notification_states;
    ?>
    <h3><?php _e( 'Smashing profile information', 'smashing' ); ?></h3>
    <table class="form-table">
        <tr>
            <th scope="row"><?php _e( 'State', 'smashing' ); ?></th>
            <td>
                <label for="state">
                    <select name="state">
                        <option value="" <?php selected( get_user_meta( $user->ID, 'state', true ), "" ); ?>>Select</option>
                        <?php foreach ($smashing_notification_states as $key => $value) { ?>
                            <option value="<?php echo $key; ?>" <?php selected( esc_attr( get_user_meta( $user->ID, 'state', true ) ), $key ); ?>><?php echo $value; ?></option>
                        <?php } ?>
                    </select>
                    <?php _e( 'Select state', 'smashing' ); ?>
                </label>
            </td>
        </tr>
        <tr>
            <th scope="row"><?php _e( 'Notifications', 'smashing' ); ?></th>
            <td>
                <label for="notification">
                    <input id="notification" type="checkbox" name="notification" value="true" <?php checked( esc_attr( get_user_meta( $user->ID, 'notification', true ) ), 'true' ); ?> />
                    <?php _e( 'Subscribe to email notifications', 'smashing' ); ?>
                </label>
            </td>
        </tr>
    </table>
<?php }        

This table contains two custom meta fields. The first is a select menu whose options are generated by a foreach loop that iterates over the $smashing_notification_states global array. This way, the user doesn’t have to type the name of their state, but instead chooses it from a dropdown list.

As you can see, we’re calling the selected() function9 twice from inside two tags; selected() is a WordPress function for comparing two strings. When the strings have the same value, the function prints selected='selected'; otherwise, it echoes an empty string.

The first time we call selected(), we’re comparing the current option’s value ('state') with an empty string (which means no state was selected). When iterating over the $smashing_notification_states array, we’re comparing the value of each element to the current value of the 'state' meta field. This way, we can automatically select the option corresponding to the existing 'state' value.

The second meta field to be added to users’ profiles is a checkbox. Its value will be 'true' or 'false' depending on whether the user chooses to receive notifications. Similar to selected(), checked()10 prints out the string checked='checked' when its two arguments have the same value. Of course, checked() applies to checkboxes and radio buttons.

Now that we’ve got the fields, we can save the user’s input. We need two action hooks to store the user data:

add_action( 'personal_options_update', 'smashing_save_user_meta_fields' );
add_action( 'edit_user_profile_update', 'smashing_save_user_meta_fields' );

Here, personal_options_update is triggered when the user is viewing their own profile page, while edit_user_profile_update is triggered when a user with sufficient privileges is viewing another user’s profile page. We have two hooks but just one callback:

/**
 * Store data in wp_usermeta table.
 *
 * @param int $user_id the user unique ID.
 */
function smashing_save_user_meta_fields( $user_id ) {

    if ( !current_user_can( 'edit_user', $user_id ) )
        return false;

    if( isset($_POST['state']) )
        update_user_meta( $user_id, 'state', sanitize_text_field( $_POST['state'] ) );

    if( !isset($_POST['notification']) ) 
        $_POST['notification'] = 'false';
    
    update_user_meta( $user_id, 'notification', sanitize_text_field( $_POST['notification'] ) );

}

This function verifies whether the user is allowed to edit_user, and if current_user_can is true, it checks the data and saves it in the wp_usermeta table.

Custom meta fields
The custom meta fields added to the user’s profile page.

Custom Meta Box And Custom Fields

We have to decide what kind of content should be included in the notification to subscribers. This decision will depend on your website’s architecture. In this example, we’ll go for regular posts, but you could choose a custom post type instead. The choice depends on your needs.

That being said, we are going to build a custom meta box containing a set of custom fields. These fields will be used to store an address, city, state and some other data related to location. Two other custom fields will enable and disable notifications on a per-post basis, and they will register the number of emails sent to users whenever a new post has been published. Let’s put another action hook to work:

add_action( 'add_meta_boxes', 'smashing_add_meta_box' );
function smashing_add_meta_box(){

    $screens = array( 'post' ); // possible values: 'post', 'page', 'dashboard', 'link', 'attachment', 'custom_post_type'

    foreach ($screens as $screen) {
        add_meta_box(
            'smashing_metabox',                     // $id - meta_box ID
            __( 'Venue information', 'smashing' ),  // $title - a title for the meta_box container
            'smashing_meta_box_callback',           // $callback - the callback that outputs the html for the meta_box
            $screen,                                // $post_type - where to show the meta_box. Possible values: 'post', 'page', 'dashboard', 'link', 'attachment', 'custom_post_type'
            'normal',                               // $context - possible values: 'normal', 'advanced', 'side'
            'high'                                  // $priority - possible values: 'high', 'core', 'default', 'low'
            );
        }
}

Here, add_meta_box11 accepts seven arguments: a unique ID for the meta box, a title, a callback function, a value for screen, the context (i.e. the part of the page where to show the meta box), and priority and callback arguments. Because we are not setting a value for the callback argument parameter, the $post object will be the only argument passed to smashing_meta_box_callback. Finally, let’s define the callback function to print out the meta box:

/*
 * Print the meta_box
 *
 * @param obj $post The object for the current post
 */
function smashing_meta_box_callback( $post ){
    global $smashing_notification_states;

    // Add a nonce field
    wp_nonce_field( 'smashing_meta_box', 'smashing_meta_box_nonce' );

    $address = esc_attr( get_post_meta( get_the_ID(), 'address', true ) );
    $city = esc_attr( get_post_meta( get_the_ID(), 'city', true ) );
    $state = esc_attr( get_post_meta( get_the_ID(), 'state', true ) );
    $zip = esc_attr( get_post_meta( get_the_ID(), 'zip', true ) );
    $phone = esc_attr( get_post_meta( get_the_ID(), 'phone', true ) );
    $website = esc_attr( get_post_meta( get_the_ID(), 'website', true ) );
    $disable = esc_attr( get_post_meta( get_the_ID(), 'disable', true ) );
    ?>
<table id="venue">
    <tbody>
        <tr>
            <td class="label"><?php _e( 'Address', 'smashing' ); ?></td>
            <td><input type="text" id="address" name="venue[address]" value="<?php echo $address; ?>" size="30" /></td>
        </tr>
        <tr>
            <td><?php _e( 'City', 'smashing' ); ?></td>
            <td><input type="text" id="city" name="venue[city]" value="<?php echo $city; ?>" size="30" /></td>
        </tr>
        <tr>
            <td><?php _e( 'State', 'smashing' ); ?></td>
            <td>
                <select name="venue[state]">
                    <option value="" <?php selected( $state, "" ); ?>>Select</option>
                    <?php foreach ($smashing_notification_states as $key => $value) { ?>
                        <option value="<?php echo $key; ?>" <?php selected( $state, $key ); ?>><?php echo $value; ?></option>
                    <?php } ?>
                </select>
            </td>
        </tr>
        <tr>
            <td><?php _e( 'Disable notification', 'smashing' ); ?></td>
            <td><input id="disable" type="checkbox" name="venue[disable]" value="true" <?php checked( $disable, 'true' ); ?> /></td>
        </tr>
    </tbody>
</table>
<?php
}

First, we’re initializing the global array and registering a nonce field12. We then add two simple text fields. The name attribute is set in the form of an array element, while the value is set to the corresponding custom field’s value. Finally, the main custom fields are added.

Just like with the user’s meta data, we add a select menu whose options are echoed, iterating over the elements in the $smashing_notification_states global array. Once we have built the select menu, let’s continue with a checkbox to enable and disable the single post notification.

Now we have to save the data: Our action hook is save_post. We’ll perform a number of tasks with the callback function. Take a look at the inline documentation for more information.

add_action( 'save_post', 'smashing_save_custom_fields' );

/*
 * Save the custom field values
 *
 * @param int $post_id the current post ID
 */
function smashing_save_custom_fields( $post_id ){

    // Check WP nonce
    if ( !isset( $_POST['smashing_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['smashing_meta_box_nonce'], 'smashing_meta_box' ) )
        return;

    // Return if this is an autosave
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;

    // check the post_type and set the correspondig capability value
    $capability = ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) ? 'edit_page' : 'edit_post';

    // Return if the user lacks the required capability
    if ( !current_user_can( $capability, $post_id ) )
        return;

    if( !isset($_POST['venue']['disable']) ) 
        $_POST['venue']['disable'] = 'false';

    // validate custom field values
    $fields = ( isset( $_POST['venue'] ) ) ? (array) $_POST['venue'] : array();
    $fields = array_map( 'sanitize_text_field', $fields );

    foreach ($fields as $key => $value) {
        // store data
        update_post_meta( $post_id, $key, $value );
    }
}

Our custom meta box is up and running, and it looks like this:

Custom meta box13
The custom meta box showing the location details. (View large version14)

Building The Notification System

If you were working with custom post types, you would need the publish_{$post_type} hook (i.e. publish_recipes, publish_events, etc.). But since we are working with posts, publish_post is the hook for us:

add_action( 'publish_post', 'smashing_notify_new_post' );

/*
 * Notify users sending them an email
 *
 * @param int $post_ID the current post ID
 */
function smashing_notify_new_post( $post_ID ){
    global $smashing_notification_states;

    $url = get_permalink( $post_ID );
    $state = get_post_meta( $post_ID, 'state', true );

    if( 'true' == get_post_meta( $post_ID, 'disable', true ) )
        return;

    // build the meta query to retrieve subscribers
    $args = array(
            'meta_query' => array(
                    array( 'key' => 'state', 'value' => $state, 'compare' => '=' ),
                    array( 'key' => 'notification', 'value' => 'true', 'compare' => '=' )
                ),
            'fields' => array( 'display_name', 'user_email' )
        );
    // retrieve users to notify about the new post
    $users = get_users( $args );
    $num = 0;
    foreach ($users as $user) {

        $to = $user->display_name . ' <' . $user->user_email . '>';

        $subject = sprintf( __( 'Hei! We have news for you from %s', 'smashing' ), $smashing_notification_states[$state] );

        $message = sprintf( __( 'Hi %s!', 'smashing' ), $user->display_name ) . "rn" .
        sprintf( __( 'We have a new post from %s', 'smashing' ), $smashing_notification_states[$state] ) . "rn" .
        sprintf( __( 'Read more on %s', 'smashing' ), $url ) . '.' . "rn";   

        $headers[] = 'From: Yourname <you@yourdomain.com>';
        $headers[] = 'Reply-To: you@yourdomain.com';

        if( wp_mail( $to, $subject, $message, $headers ) )
            $num++;
    }
    // a hidden custom field
    update_post_meta( $post_ID, '_notified_users', $num );
    return $post_ID;
}

Once again, we declare the global array $smashing_notification_states. The two variables $url and $state will store the post’s permalink and state. The succeeding condition checks the value of the disable custom field: If it’s 'true', we exit the function. We have to retrieve from the database all users whose state meta field has the same value as the state custom field of the current post, and we use the get_users() function to accomplish this.

The wp_mail15 function accepts five arguments: recipient(s), subject, message, headers, attachments. The recipients could be passed as an array or as a comma-separated strings of addresses. So, we could have passed to the function all of the addresses together, but doing so would have made them publicly visible (this is the way wp_mail() works).

So, we’ll iterate over the $users array and call wp_mail repeatedly (which shouldn’t be done with a huge number of emails, as we’ll see in a moment). In case of success, wp_mail returns true. The counter is incremented by 1, and the loop continues with the next user.

When the foreach cycle ends, the current value of $num is registered in the hidden _notified_users custom field (notice the underscore preceding the name of the custom field).

Unfortunately, a loop iterating over and over hundreds of times could considerably slow down the script, as pointed out in the reference on the PHP mail() function16:

It is worth noting that the mail() function is not suitable for larger volumes of email in a loop. This function opens and closes an SMTP socket for each email, which is not very efficient.

For the sending of large amounts of email, see the » PEAR::Mail17, and » PEAR::Mail_Queue18 packages.

We could work around this, passing to the function the email addresses as BCCs, setting them in the headers19, as shown here:

function smashing_notify_new_post( $post_ID ){
    global $smashing_notification_states;

    $url = get_permalink( $post_ID );
    $state = get_post_meta( $post_ID, 'state', true );

    if( 'true' == get_post_meta( $post_ID, 'disable', true ) )
        return;

    // build the meta query to retrieve subscribers
    $args = array(
            'meta_query' => array(
                    array( 'key' => 'state', 'value' => $state, 'compare' => '=' ),
                    array( 'key' => 'notification', 'value' => 'true', 'compare' => '=' )
                ),
            'fields' => array( 'display_name', 'user_email' )
        );
    // retrieve users to notify about the new post
    $users = get_users( $args );

    $num = 0;

    $to = 'Yourname <you@yourdomain.com>';

    $subject = sprintf( __( 'Hei! We have news for you from %s', 'smashing' ), $smashing_notification_states[$state] );

    $message = __( 'Hi ', 'smashing' ) . "rn" .
        sprintf( __( 'We have a new post from %s', 'smashing' ), $smashing_notification_states[$state] ) . "rn" .
        sprintf( __( 'Read more on %s', 'smashing' ), $url ) . '.' . "rn";  

    $headers[] = 'From: Yourname <you@yourdomain.com>';
    $headers[] = 'Reply-To: you@yourdomain.com';

    foreach ($users as $user) {
        $headers[] = 'Bcc: ' . $user->user_email;
        $num++;
    }

    if( wp_mail( $to, $subject, $message, $headers ) )
        update_post_meta( $post_ID, '_notified_users', $num );
    
    return $post_ID;
}

As you can see, in case of wp_mail()‘s success, we update the _notified_user custom field with $num‘s value. However, in the code above, $num stores the number of retrieved users, not the number of times we call wp_mail().

Finally, if none of the solutions presented fit your needs, you could consider a third-party email notification system, such as MailChimp20 or FeedBurner21, which enable you to deliver notifications from a website’s feed.

A Note About Status Transitions

We hooked the smashing_notify_new_post callback to the publish_post action. This hook is triggered each time the status of an existing post is changed to publish. Unfortunately, publish_post is not fired when a new post is published. So, to send notifications, first save the post as “draft” (or “pending”). If you prefer to email subscribers each time a post is published, consider calling the save_post action instead:

add_action( 'save_post', 'smashing_notify_new_post' );
/*
 * Save the custom field values
 *
 * @param int $post_id the current post ID
 */
function smashing_notify_new_post( $post_ID ){
    global $smashing_notification_states;

    if( 'publish' != get_post_status( $post_ID ) )
        return;

    ...
}

Check the Codex for further information about status transitions22 and the save_post action hook23.

A Confirmation Message

When you work with the publish_post action hook, you will soon realize that testing your scripts can get a little tricky. When a new post is published, WordPress loads a script that saves data and, when it is done, redirects the user to the post-editing page. This double redirection does not allow variable values to be printed on the screen.

A confirmation message could be a good workaround. This solution allows us to check a variable’s values and to give the publisher useful information: specifically, the number of times wp_mail has been called (or the number of users to be notified).

Remember the $num variable? Its value was stored in a hidden custom field, _notified_users. Now we have to retrieve that value and print it out in a message using a filter hook.

Thanks to the post_updated_messages filter, we can customize WordPress confirmation messages and output them to the screen whenever a new post is saved or published (the Codex does not provide a reference for this filter hook, only an example of usage24). Here is the callback function we can use to customize the message when a post is published:

add_filter( 'post_updated_messages', 'smashing_updated_messages' );

/**
 * Post update messages.
 *
 * See /wp-admin/edit-form-advanced.php
 *
 * @param array $messages Existing post update messages.
 *
 * @return array Amended post update messages with new update messages.
 */
function smashing_updated_messages( $msgs ){

    $post = get_post();
    $post_type = get_post_type( $post );
    $post_type_object = get_post_type_object( $post_type );

    $num = get_post_meta( $post->ID, '_notified_users', true );

    if ( $post_type_object->publicly_queryable ) {
        $msgs[$post_type][6] .= ' - ' . $num . __( ' notifications sent.', 'smashing' );
    }
    return $msgs;
}
A custom message
When a post is published, a custom message is printed informing the author about the number of emails sent to users.

wp_mail Function And SMTP

WordPress’ wp_mail() function works the same way as PHP’s mail() function. Whether an email has been successfully sent will depend on php.ini‘s settings, but most hosts include SMTP in their services. If you aren’t able to set that up, you could choose an external SMTP service and use it in tandem with the WP Mail SMTP25 plugin, which routes your emails through an SMTP service.

WP Mail SMTP configuration panel26
WP Mail SMTP’s settings page. (View large version27)

Be careful when you save data: the “from” field should have the same value as your account’s email address; otherwise, the server might respond with an error message.

Be aware that a plugin is not necessary: WordPress allows for the possibility of overwriting php.ini‘s settings from within a script, with the phpmailer_init action hook. This hook allows us to pass our own parameters to the PHPMailer28 object. See the Codex for more information29 on this.

Designing Better Emails

Just like the PHP mail() function, wp_mail()‘s default Content Type is text/plain. And just like the mail() function, wp_mail() allows us to set the Content Type to text/html. You can specify a different Content Type using the wp_mail_content_type filter or by setting the following headers:

$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-Type: text/html; charset=ISO-8859-1";

Of course, a number of plugins allow you to manage your email’s Content Type from the administration panel. WP Better Emails30 is just one, but it’s one of the most appreciated. This plugin forces WordPress to send HTML emails, but it’s not its only feature. It also allows administrators to build their own email templates and to send arbitrary emails for testing purposes.

Finally, the following image shows what will be delivered to a Gmail user’s inbox.

Description of the image.31
The result in Gmail: The content has been generated by our code; SMTP parameters have been saved on WP Mail SMTP’s settings page; and the template is provided by WP Better Emails. (View large version32)

Conclusion

Our notification system is ready to be used. In building it, we’ve toured many of WordPress’ core features: user meta fields, custom meta boxes, custom queries, the mailing from script and more. If you’re interested, download the full code33 (ZIP file), and remember to switch each occurrence of the you@yourdomain.com string with your own email address.

You can expand on this a lot more. You could integrate this system with a third-party email management application such as MailChimp34 or Mad Mimi35. You could design flashy email templates. Or you could create even more personalized notifications.

Further Reading

(dp, al, ml)

Footnotes

  1. 1 http://jetpack.me/support/subscriptions/
  2. 2 https://wordpress.org/plugins/subscribe2/
  3. 3 http://www.smashingmagazine.com/wp-content/uploads/2015/04/subscribe2-large-preview-opt.png
  4. 4 http://www.smashingmagazine.com/wp-content/uploads/2015/04/subscribe2-large-preview-opt.png
  5. 5 http://codex.wordpress.org/Writing_a_Plugin
  6. 6 http://codex.wordpress.org/Database_Description
  7. 7 http://codex.wordpress.org/Plugin_API/Action_Reference/show_user_profile
  8. 8 http://codex.wordpress.org/Plugin_API/Action_Reference/edit_user_profile
  9. 9 http://codex.wordpress.org/Function_Reference/selected
  10. 10 http://codex.wordpress.org/Function_Reference/checked
  11. 11 http://codex.wordpress.org/Function_Reference/add_meta_box
  12. 12 http://codex.wordpress.org/WordPress_Nonces
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2015/04/venue-large-preview-opt.png
  14. 14 http://www.smashingmagazine.com/wp-content/uploads/2015/04/venue-large-preview-opt.png
  15. 15 http://codex.wordpress.org/Function_Reference/wp_mail
  16. 16 http://php.net/manual/it/function.mail.php
  17. 17 http://pear.php.net/package/Mail
  18. 18 http://pear.php.net/package/Mail_Queue
  19. 19 http://codex.wordpress.org/Function_Reference/wp_mail#Using_.24headers_To_Set_.22From:.22.2C_.22Cc:.22_and_.22Bcc:.22_Parameters
  20. 20 http://kb.mailchimp.com/campaigns/rss-in-campaigns/create-an-rss-driven-campaign
  21. 21 https://support.google.com/feedburner/answer/78982?hl=en
  22. 22 http://codex.wordpress.org/Post_Status_Transitions
  23. 23 https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
  24. 24 http://codex.wordpress.org/Function_Reference/register_post_type#Example
  25. 25 https://wordpress.org/plugins/wp-mail-smtp/
  26. 26 http://www.smashingmagazine.com/wp-content/uploads/2015/04/wp_email_smtp-large-opt.png
  27. 27 http://www.smashingmagazine.com/wp-content/uploads/2015/04/wp_email_smtp-large-opt.png
  28. 28 http://phpmailer.worxware.com/
  29. 29 https://codex.wordpress.org/Plugin_API/Action_Reference/phpmailer_init
  30. 30 https://wordpress.org/plugins/wp-better-emails/
  31. 31 http://www.smashingmagazine.com/wp-content/uploads/2015/04/better_email-large-preview-opt.png
  32. 32 http://www.smashingmagazine.com/wp-content/uploads/2015/04/better_email-large-preview-opt.png
  33. 33 http://provide.smashingmagazine.com/sm-email-notification.zip
  34. 34 http://mailchimp.com/
  35. 35 https://madmimi.com/
  36. 36 http://www.smashingmagazine.com/2011/10/25/create-perfect-emails-wordpress-website/
  37. 37 http://codex.wordpress.org/Post_Status_Transitions
  38. 38 http://codex.wordpress.org/Plugin_API/Action_Reference
  39. 39 http://codex.wordpress.org/Plugin_API/Filter_Reference
  40. 40 http://codex.wordpress.org/Custom_Fields
  41. 41 https://developer.wordpress.org/plugins/metadata/creating-custom-meta-boxes/
  42. 42 http://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
  43. 43 https://codex.wordpress.org/Data_Validation

The post Building An Advanced Notification System For WordPress appeared first on Smashing Magazine.

Categories: Others Tags:

20+ Fresh Free Templates in HTML/CSS and PSD plus GUI Packs (May 2015)

May 20th, 2015 No comments

The fifth iteration of our monthly series waits for you to be explored. If you’re a web designer reading this, you’re in for a treat. We just put together our latest collection of fresh resources to build websites through templates and amazing UI kits, plus a little bonus. Free some space on your hard drive and enjoy these neat freebies. One important information before you read on: All the following elements are freely usable, though some will require a registration to download and not all are suitable for commercial use. More detailed license information is provided individually, but keep in mind that it’s always best to double-check licensing before you actually use a resource, at least commercially. Photon Template Created by/for: HTML5 UPFeatures: beautiful animations, simple and effective one-page layoutLicense: Creative Commons Attribution Material Design UI Pack Created by/for: Released by ByPeople, created by DesigntoryFeatures: modern look, free fonts used, customizable vector shapesLicense: free for personal and commercial use Fimply One Page HTML Template Created by/for: Shape BootstrapFeatures: Filterable portfolio, CSS3 animations, Google Fonts supportLicense: free for personal and commercial use (MIT License) KreFolio: Landing Page Template Created by/for: Shape BootstrapFeatures: One page template, business oriented, .htaccess file for improved cachingLicense: free for personal and […]

Categories: Others Tags:

Testing For And With Windows Phone

May 19th, 2015 No comments
Rendering on the Nokia Lumia 920

Although Windows Phone usage is still low compared with other browsers1 it’s sometimes necessary to test your web work for Internet Explorer Mobile. For web developers, this could be a complication. Testing for the Windows Phone environment is not always optional, but it can be a chore — especially because the version of Internet Explorer that comes with the Windows Phone can be quirky at best. If you’re a developer without a Windows Phone device, you might have to get a little creative to ensure that your websites are being rendered properly.

The Nokia Lumia 920. (Image credit: Microsoft2)

In this article I want to point out a few different tools and techniques which can help test websites for Windows Phone even if you don’t have the real device handy or if you are not developing on Windows. But first let’s quickly look into the differences between mobile and desktop Internet Explorer.

IE Mobile Explained

As Microsoft acknowledged in the past, the version of Internet Explorer found on mobile devices is similar but not identical3 to the desktop browser version. There are a few key features that are not available on Windows Phone:

These are all rather minor features but you still need to know about the rendering differences and take these into account.

Testing Tools

Accuracy is not always the most important thing about this kind of testing. During development it’s more important to test and iterate quickly than get a pixel-perfect implementation on the first try. But you do need to know how accurate your testing method is so you can plan the final test accordingly.

To help you get a sense of the accuracy of each testing method we’ll compare each test tool against the rendering of two websites on a real device (Nokia Lumia 920). For reference, let’s see how SmashingMag7 (responsive) and Quirksmode8 (not responsive) render on a real Windows Phone device:

9
Rendering on the Nokia Lumia 920. (View large version10)

Later in the article we’ll compare the original rendering with the rendering in the test tool to see how accurate the tool is. In the best case, a testing tool will produce the exact same rendering as the real device, with 100% accuracy. Let’s dive right in, shall we?

Internet Explorer Emulation

The fastest and easiest way to test a site for the Windows Phone environment is to use Internet Explorer and its built-in emulator service. Through the developer tools provided in the browser itself, you will be able to run a phone emulation. This includes options such as the browser profile, orientation and screen resolution. You can flip through settings in real time to look at different devices and resolutions, and you can complete testing locally on your computer before the site goes live. Furthermore, you can switch between the mobile versions of the website and the desktop version to ensure that none of your changes have affected the way the site looks on the desktop version of Internet Explorer.

Just like the device simulation in Chrome, this sounds like a great idea and an easy solution for quick testing. Most likely you’ll need to test for Internet Explorer at some point, so why not integrate Windows Phone into this testing step?

Nokia Lumia (left), IE emulation (right)11
Nokia Lumia (left), IE emulation (right). (View large version12)

Unfortunately the rendering results show us that the emulation inside Internet Explorer is not yet reliable for testing responsive websites.

Nokia Lumia (left), IE emulation (right)13
Nokia Lumia (left), IE emulation (right). (View large version14)

It seems like the emulation ignores any viewport settings and just resizes the page so it fits the screen. While this is one of the fastest methods of seeing a website in a Windows Phone environment, it’s mostly useful for quick checks of websites that are not responsive rather than more comprehensive testing.

Windows Phone Emulator

For designers who value accuracy more than a lightweight testing option, there is a Windows Phone Emulator3715 available for both Windows Phone 7 and Windows Phone 8. If you are not on Windows the emulators can also be used through a service such as BrowserStack16.

The standalone Windows Phone emulator is much better than the emulation embedded into Internet Explorer. The emulator runs a copy of the entire Windows Phone operating system, so you can test native applications alongside your web project. It’s the ideal solution for those who simply need to test on that one platform; using the emulator online may be a more comprehensive option for those who need to do a lot of cross-platform testing.

Nokia Lumia (left), Windows Phone emulator (right)17
Nokia Lumia (left), Windows Phone emulator (right). (View large version18)

As the results show, the Windows Phone emulator is not quite as accurate in rendering as you would hope. In particular, the SVG icons of SmashingMagazine in the top-right do not work in the emulator, but display as intended on the actual device.

Nokia Lumia (left), Windows Phone emulator19
Nokia Lumia (left), Windows Phone emulator. (right) (View large version20)

The emulator has some system limitations. For instance, the Windows Phone 8 emulator only runs on Windows 8 and higher. For those who have Mac OS X or other operating systems, it’s impossible to install and use the emulator directly without using a virtual machine. Using a web-based solution is usually the best option.

As with all emulators, although the emulator provided by Microsoft is likely the most accurate available, it still won’t be able to display the site with complete accuracy for each device. Some hardware issues remain that cannot be compensated for by an emulator. Still, the Windows emulator is probably the best emulator that you can find should you want to use a software emulator.

Real Device

The best method of testing for Windows Phone is undoubtedly testing with a real device. As we’ve seen, the emulator comes close but is not as accurate as we would like it to be. And, of course, there are certain things that just can’t be simulated or emulated. For instance, the user experience might be altered by the way that the user needs to manipulate their touchscreen. When using a real device, most developers will focus on Windows Phone 8 as Windows Phone 7 is already in decline21. The browser rendering may also vary depending on device, as the device resolution will differ from mobile device to mobile device.

If you don’t want to purchase a dedicated testing device I would recommend you take a look at the services offered by Perfecto Mobile22, CrossBrowserTesting.com23 or DeviceAnywhere4124, which give you online access to Windows Phone devices among many more. These real devices render just like my testing device so you’ll be one the safe side here.

If you want to purchase a testing device you can go with the high-end solution and purchase the most powerful Lumia 152025; choose something in the middle like the Lumia 92026; or stick to the low end with a Lumia 43027, the cheapest Windows Phone.

Remote Debugging

Now that you can find all the design bugs, how can you fix them? I find nothing more frustrating than relying on random guesswork to fix a bug. Luckily you can use weinre28 (WEb INspector REmote) to get a decent remote debugger going for Windows Phone. It’s similar to remote debugging on Android in Chrome29 but with fewer features.

Weinre

Weinre is an open source remote debugging tool for debugging websites on a Windows Phone (and any other mobile device, of course). As an open source tool, it is entirely free and more advanced developers can even modify its code. Microsoft even advises developers to use weinre30 to debug on Windows Phone.

With weinre you are able to inspect the DOM and change it on the fly, allowing for real-time changes. Though the tool does not allow for advanced features like JavaScript debugging — the entire thing runs on JavaScript, which limits it a little — it’s still an excellent solution for remote testing and debugging.

Using weinre is really easy. It runs on Node.js31. With two simple commands you can install and start the weinre server. On Windows:

npm -g install weinre
weinre --httpPort 8080 --boundHost -all-

And on Mac OS X and Linux:

sudo npm -g install weinre
weinre --httpPort 8080 --boundHost -all-

Weinre will now run at your localhost:8080. To debug your Windows Phone device you need to follow the steps below:

  • Open localhost:8080 on your development machine.
  • In the Target Script section of the website that opens you’ll find the element you need to add to the website you want to test.
  • Now open the page on your Windows Phone as normal.
  • On your development machine, the developer tools are now available here: localhost:8080/client/#anonymous.

Note that weinre is a debugging tool should never be run in production as this could pose a security risk32.

Web Inspector Remote33
Web Inspector Remote. (View large version34)

If you want to use weinre as a development tool, you will need to have the devices that you intend to test for either physically, in the cloud, or emulated. Still, it is an excellent method of testing in real time and should be included in the arsenal of any web developer. The weinre debugging environment can be opened in any major browser.

What about Windows Phone 10?

As the time of writing no web service offered testing on the beta version of Windows Phone 10, and currently there is no device available which will have it preinstalled. But if you want to test for the upcoming new operating system you can either update your device35 to Windows 10 or run the emulator inside a Windows 10 installation36 on your desktop machine using the latest Windows Phone SDK and Visual Studio 2013.

Summary

How does your website look on the Windows Phone platform? Approximately 3% of your mobile users will be using a Windows Phone — so you may need to make sure that your site renders properly. As we’ve seen, it’s not that easy to test for Windows Phone as all testing tools (even the emulator by Microsoft) don’t render that reliably. I suggest going with one of the online services to access the real device as this works rather well. The only downside is that weinre will not work if you don’t make your development machine reachable externally.

Resources

(da, ml, og)

Footnotes

  1. 1 https://www.netmarketshare.com/browser-market-share.aspx?qprid=0&qpcustomd=1
  2. 2 http://www.microsoft.com
  3. 3 https://msdn.microsoft.com/en-us/library/ie/dn736066%28v=vs.85%29.aspx
  4. 4 http://html5demos.com/drag
  5. 5 https://msdn.microsoft.com/en-us/library/ie/bg182646(v=vs.85).aspx#eme
  6. 6 http://www.hongkiat.com/blog/css3-hyphenation/
  7. 7 http://www.smashingmagazine.com
  8. 8 http://www.quirksmode.org
  9. 9 https://www.smashingmagazine.com/wp-content/uploads/2015/04/02-device-rendering-opt.png
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2015/04/02-device-rendering-opt.png
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2015/04/03-mag-ie-opt.png
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2015/04/03-mag-ie-opt.png
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2015/04/04-q-ie-opt.png
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2015/04/04-q-ie-opt.png
  15. 15 https://msdn.microsoft.com/en-us/library/windows/apps/ff402563%28v=vs.105%29.aspx
  16. 16 http://www.browserstack.com
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2015/04/05-mag-emulator-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2015/04/05-mag-emulator-opt.png
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2015/04/06-q-emulator-tops.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2015/04/06-q-emulator-tops.png
  21. 21 http://techcrunch.com/2014/11/27/windows-phone-8-1-finally-breaks-the-50-market-share-threshold/
  22. 22 http://perfectomobile.com
  23. 23 http://www.crossbrowsertesting.com
  24. 24 https://www.keynote.com/solutions/testing/mobile-testing
  25. 25 http://www.microsoft.com/de-de/mobile/smartphone-handy/lumia1520/
  26. 26 http://www.microsoft.com/en/mobile/phone/lumia920/
  27. 27 http://www.microsoft.com/en/mobile/phone/lumia430-dual-sim/specifications/
  28. 28 http://people.apache.org/~pmuellr/weinre-docs/latest/
  29. 29 https://developer.chrome.com/devtools/docs/remote-debugging
  30. 30 https://msdn.microsoft.com/en-us/library/windows/apps/ff402563%28v=vs.105%29.aspx
  31. 31 https://nodejs.org/
  32. 32 http://people.apache.org/~pmuellr/weinre-docs/latest/Security.html
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2015/04/07-weinre-opt.png
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2015/04/07-weinre-opt.png
  35. 35 http://www.ibtimes.co.uk/how-install-windows-10-technical-preview-phones-any-windows-phone-8-1-device-1488013
  36. 36 http://www.codefoster.com/wponwin10/
  37. 37 https://msdn.microsoft.com/en-us/library/windows/apps/ff402563%28v=vs.105%29.aspx
  38. 38 http://www.crossbrowsertesting.com/
  39. 39 http://www.browserstack.com/
  40. 40 http://perfectomobile.com/
  41. 41 https://www.keynote.com/solutions/testing/mobile-testing
  42. 42 http://visualstudiomagazine.com/articles/2013/06/13/test-and-debug-html5-apps-remotely.aspx

The post Testing For And With Windows Phone appeared first on Smashing Magazine.

Categories: Others Tags: