• Aucun résultat trouvé

Building WordPress !emes You Can Sell

N/A
N/A
Protected

Academic year: 2022

Partager "Building WordPress !emes You Can Sell"

Copied!
164
0
0

Texte intégral

(1)
(2)

Imprint

Published in November 2011

Smashing Media GmbH, Freiburg, Germany

Cover Design: Ricardo Gimenes

Editing: Andrew Rogerson, Talita Telma Proofreading: Andrew Lobo, Iris Ljesnjanin

Idea and Concept: Sven Lennartz, Vitaly Friedman

Founded in September 2006, Smashing Magazine delivers useful and innovative information to Web designers and developers. Smashing Magazine is a well-respected international online publication for

professional Web designers and developers. Our main goal is to support the Web design community with useful and valuable articles and resources, written and created by experienced designers and developers.

ISBN: 9783943075168

Version: December 16, 2011

(3)

Table of Contents

Preface

Building WordPress !emes You Can Sell Developing WordPress Locally With MAMP

!e Developer’s Guide To Conflict-Free JavaScript And CSS In WordPress

Interacting With !e WordPress Database How To Create A WordPress Plugin

How To Integrate Facebook With WordPress How To Use AJAX In WordPress

Be"er Image Management With WordPress

Using HTML5 To Transform WordPress’ TwentyTen !eme

!e Authors

(4)

Preface

The advanced flexibility of WordPress is one of the main reasons for its popularity among online publishers as it is considered as the number one blogging tool in its category. With its latest releases, it has extended its potential well beyond blogging, moving toward an even more advanced, robust and very powerful content management solution, and so much more.

However, where it falls short, there are a wealth of plugins, widgets and themes that extend its limitations.

This Smashing eBook #10: WordPress Essentials is created to help Web developers as well as designers how to extend the functionality of

WordPress with plugins and introduce techniques and methods for customizing themes. Several new features were added which make

WordPress manage media even more practical, and this eBook is going to show you just how.

The eBook contains 9 articles that will guide you on how to add and

organize media, to avoid problems with JavaScript and CSS, build themes, interact with your database, and learn how to setup AJAX ― just to mention a few techniques. Social networks are a wonderful marketing tool that

should not be ignored. Find out how to present your WordPress blog on Facebook, as well!

The articles have been published on Smashing Magazine in 2010 and 2011, and they have been carefully edited and prepared for this eBook.

We hope that you will find this eBook useful and valuable. We are looking forward to your feedback on Twitter or via our contact form.

— Andrew Rogerson, Smashing eBook Editor

(5)

Building WordPress !emes You Can Sell

Sawyer Hollenshead

When I took my first steps into the WordPress theme arena, I didn’t know much about it. I wandered blindly into the business, not knowing whether I was doing things correctly. Over time, through trial and error and making rookie mistakes, I learned some valuable lessons and gained important insights. To save you from going down the same winding path, I’ll share some of the important takeaways that I’ve learned so far, like how to gain a solid user base, what to include in your themes and, most importantly, what to leave out.

(6)

Gaining a Solid User Base

You could build the best WordPress theme in the world, but it won’t matter unless people know about it and use it. One of the smartest things I did when starting my theme business was to release a free theme. It took a while for it to gain traction, but things took off once it got some attention from being featured on other websites. Consumers are willing to download a free theme from the new kid on the block and try it out because hardly any financial risk is involved.

The free theme was unique and easy to use, and people liked it so much that they began requesting a premium (i.e. commercial) version, with more features (the free version had the bare essentials). To this day, the premium version is still one of my best sellers. Consumers like to download the free version to try it out, and then they typically purchase the commercial

version. Value is added to the commercial version with support, updates, easier customization and a bundle of exclusive features. Releasing a free theme enabled me to gain momentum and build on a solid user base as I began creating commercial themes, and I’ll return to that strategy in the future to increase sales.

MY FIRST MISTAKE

The first mistake I made when getting started, and one that I still kick myself over, is that I didn’t implement a newsletter opt-in method for users who downloaded my themes. This would have given me a long list of consumers to whom I could market my premium themes, and it would have been

extremely valuable when I launched the commercial version of my theme a year later. I’ve now gotten my act together and have a booming mailing list that I email every time I release a new theme, thus generating sales that would otherwise have been lost.

(7)

YOU’VE GOT ’EM, NOW KEEP ’EM

Once I had a solid user base, I found that in order to keep them as returning customers, I had to add value not only to my themes but to my services.

When you start a theme business, you’re not just selling themes; you’re also providing support and updates. Some of the top brands make great

products and provide excellent support. Think of Apple, MediaTemple and Zappos. Say what you want about these companies, but there’s no denying that their user base is loyal because of both their products and their support and services.

One way to provide great support is simply to be timely with your

responses. A customer loves nothing more than being responded to the same day. If you don’t know the answer to their question, at least let them know that you received it and are looking into it. You would think this is common practice, but you’d be amazed at how long some companies take to respond. If you can provide killer support, you’re already one step ahead of a lot of the competition.

Another way to add value is to provide educational resources that teach customers how to get the most out of your products. Some users will be more advanced than others, and they are usually the ones who purchase themes regularly. If you can provide a resource that enables those users to derive extra value from your products, then they will be more likely to stay with you and purchase more of your themes.

(8)

Streamline Your Process

Streamline and standardize your development process as much as possible.

One way to do this is to use a theme framework, whether your own or a third party’s. Using a framework to quickly develop a theme is important when an eager audience is waiting on you. Most importantly, when you use the same framework, updating all of your themes after they’ve been

released is easier. For example, all of my themes display a notification in the administration panel when an update becomes available.

The code that enables this notification is in a file named framework-init.php.

In this file is a bunch of other important blocks of code that add features, such as the theme options panel and custom post fields, as well as common functions used throughout all of my themes. When I need to update that code, I simply make the change to my framework’s file and then that file gets replaced in all of my themes. By knowing that the file is the same throughout all of my themes, I don’t have to bother going through each theme to find that block of code to update. You can see how this becomes valuable when your inventory starts to accumulate.

(9)

Hybrid is one of the more popular theme frameworks, thanks to its extensive list of features, including translations into 20+ languages and theme hooks.

CUSTOM VS. THIRD-PARTY FRAMEWORKS

From the beginning, I decided to build my own framework, mainly because I would know it back to front, making it easier to maintain and build on (being a control freak might have contributed to the decision as well). A custom framework also meant that I wouldn’t have to rely on someone else, and the framework would have exactly what I needed and nothing else.

(10)

This is, of course, just personal preference, and many people prefer to use a third-party framework. By using a third party’s, you save the time it takes to develop a solid framework. It also means that you’re not solely responsible for maintaining the framework, and you will usually have a support system to turn to if you run into development issues. A lot of impressive frameworks offer useful functionality, such as theme hooks, extensible layout options, styling for popular plugins and much more. Lastly, there is a growing market for child themes of such frameworks as Genesis, StartBox and Hybrid.

What To Include In Your !eme

Depending on the type of theme you’re creating, the expectations of consumers will vary. But you should consider certain features and

functionality for the majority of your themes. You needn’t implement all of these, but at least consider whether they would add value to your theme.

INTERNATIONALIZE THE THEME FOR OTHER LANGUAGES

Internationalizing your theme enables users to translate the text displayed by your theme, and implementing it is fairly straightforward. This one is a must-have. I was amazed at how many non-English-speaking users

downloaded my themes. Looking back, I should have internationalized my themes from the beginning, knowing that millions of people all over the world use WordPress. You would be silly not to internationalize your theme.

Look at the “Translating WordPress” section of the Codex and this helpful tutorial by AppThemes for more information.

(11)

SUPPORT WORDPRESS’ CODING STANDARDS AND PRACTICES Develop your themes in a way that supports WordPress’ latest coding standards and practices. In doing so, you ensure that the theme is

compatible with future versions of WordPress, and you’ll avoid a flood of emails from customers who have run into conflicts. Also, avoid deprecated functions, which are functions that are “no longer supported and may be removed in future versions of WordPress.”

An easy way to check all of this is to install the Theme-Check plugin. This great little plugin runs the same tests as those that WordPress.org runs on submitted themes.

The Theme-Check plugin has saved me many times from leaving out important details and using deprecated functions.

(12)

DOCUMENTATION AND READABLE CODE

Write thorough and helpful documentation for your themes. This will not only help users, but also cut down on the number of support requests you get from aggravated users. And trust me: the less support requests you get, the happier you will be. Document everything that’s unique about your

theme that WordPress users might be unfamiliar with, as well as any built-in features such as custom backgrounds and headers, menus, and post

formats. Also provide instructions on how to update the theme and on the proper way to customize the code (in case a user wants to create a child theme).

The Twenty Eleven theme is a good example of a theme with well-documented code.

(13)

Another important aspect of documentation is to make the code easy to read and understand. Some advanced users will want to customize the code, so it should be commented in a way that helps them understand what you’ve done under the hood. For a good example of well-documented code, check out the functions.php file in the default Twenty Eleven theme.

CHILD THEMEABLE

As noted, many users will want to customize the code. The trick is that, when you release an update, the developer has to avoid overwriting the files that they’ve customized. The solution is for them to make their

customizations in a child theme. So, make sure to support this functionality by allowing child themes to be easily created.

If you don’t want users to have to worry about including a particular script when creating a child theme, then use the

get_template_directory_uri(); function to reference the parent theme’s folder. To allow the developer to overwrite this file, use

get_stylesheet_directory_uri(); instead, which references the folder in the child theme, if one is being used.

PAGE TEMPLATES

Your theme should support the various page templates that a WordPress website can have. Because you don’t know how each developer will use the theme, you have to prepare for all possibilities. This is where testing comes in. For a typical WordPress theme, you should at the very least support these templates: page.php, archive.php, 404.php, search.php, single.php, attachment.php and, of course, index.php, which is the ultimate fallback. For a full list of templates, check out the “Template Hierarchy” section of the WordPress Codex.

(14)

WordPress’ “Template Hierarchy“ is a great reference to have on hand.

You can also provide users with custom page templates. The two most common that I include with my themes is one with a widgetized sidebar (the default page.php) and one with a full-width page. You’ll likely be able to come up with other templates that users would benefit from once you’ve designed the theme.

(15)

Some theme developers use custom fields for this functionality, instead of page templates. This seems counterintuitive because the functionality is built into WordPress and is so simple to use. Creating your own page template is as easy as creating a new PHP file in the theme’s folder and adding the following PHP comment at the top (replacing “Full Width” with the template name of your choice):

<?php /*

Template  Name:  Full  Width

*/

?>

Of course, the code that follows the line above is up to you and will determine what the template does.

A NOTE ON THEME OPTIONS

There seems to be a misunderstanding about what users of premium

themes expect. The common belief is that they expect an options panel that looks like the control panel of a Boeing 747, where they can tweak the

smallest detail of the theme. Sure, users want to be able to control certain aspects of their website, but simplicity and ease of use trump bloat and complexity.

(16)

Your options panel shouldn’t be this complicated. (Image: Fly For Fun)

When deciding whether to include an option in your theme, consider

whether it’s really necessary and whether that functionality is already built into WordPress. The more options you add, the more complicated the code becomes and the steeper the learning curve for users. I keep the options for my themes to the bare essentials, and a goal of mine is to create a theme for which an options panel isn’t even necessary. I challenge you to do the same.

You can build your theme’s options on top of any one of the several great options frameworks. These are the ones I’ve come across: Options

Framework, UpThemes-Framework, OptionTree.

(17)

APPEARANCE OPTIONS

One reason to include an options panel is to enable the user to tweak the appearance of the theme without having to mess with the code. The option demanded by most users is surely to be able to upload a logo. Adding a logo is the easiest way for a user to personalize their theme. I enable it in all of my themes.

A snapshot of the options page in my latest commercial theme (based on the Options Framework).

(18)

Most theme buyers aren’t designers. They might not have an eye for color or be able to make informed design decisions. So, in addition to providing options to customize the theme’s main elements (like the color of text, the color of the call-to-action button, etc.), I include a selection of “skins,” which are basically just pre-defined palettes that a user can select from. This way, if the user doesn’t have an eye for color, they at least have options and aren’t restricted to one scheme. I usually provide several styles that cater to a variety of audiences.

SOCIAL NETWORK OPTIONS

Most individuals and businesses have some type of presence on social networks, whether on Twitter, Facebook, YouTube or whatever the next big thing is. Because the design and placement of these social-network links vary from theme to theme, you can provide an option that allows users to customize the links.

Aside (and a little plug): I used to recommend including social-network options in the theme’s panel, but having given it more thought, I now feel it’s better suited to a plugin. New social networks pop up every day, and

anticipating which ones your theme’s users will be on is hard. You will never be able to cover all bases, which is why I recently built a plugin that I’ll soon be supporting in all of my themes, and I suggest you do the same if you plan on including this feature. The plugin adds a new settings page where the user can create a list of social-network links. Users can select from the range of icons built into the plugin or built into the theme (if present) or upload their own. If this interests you, the plugin is called Social Bartender and is in the WordPress repository.

(19)

ADVERTISING OPTIONS

You could also enable users to add advertisements, either through a widget or through an option that positions the ads in certain spots (like following the top blog post). Many people want to monetize their website and so advertising options would be important to them. Being able to select the locations of ads to suit the design is a selling point.

What To Leave Out

Almost as important as what to include in the theme is what to leave out.

Many themes have options and functionality that are better done as plugins or that are already built into WordPress. Use the functionality that

WordPress already supports, such as custom backgrounds, headers, post thumbnails and post formats. This is easier to implement because

WordPress does all of the heavy lifting, and many users are already familiar with it. That being said, if your theme doesn’t need this functionality, then don’t include it in the first place!

(20)

Shortcodes should not replace standard HTML tags. Many of the shortcodes shown above are unnecessary.

SHORTCODES

Shortcodes are great for executing a set of functions, but they’re

unnecessary simply to embed a link or add a class to an element. Use standard HTML tags for this. For example, don’t create a [quote]

shortcode when the HTML <blockquote> tag does a perfectly good job.

(21)

I’ve seen themes that have shortcodes for quotes, citations and headers but no support for the same styling with HTML tags. This is a big no-no. Many users will switch from theme to theme and will already have content on their website when they activate yours. HTML tags will stay the same, but

shortcodes vary from theme to theme. Don’t force the user to go back through all of their content just to add your custom shortcodes. Use

shortcodes only to execute functions, not to apply styling. There may be a few exceptions, such as to wrap a message in complicated HTML, but if you’re simply adding a class, then adding it to the “Format” menu in the post editor’s kitchen sink makes more sense.

A great tutorial was recently published by Luke McDonald that details how to add your own styles to the drop-down menu in the visual editor, giving you one more reason not to use shortcodes to style elements.

PLUGIN TERRITORY

Don’t include options for things that should really be added with existing plugins; for example, Google Analytics and favicons. I hear someone in the back asking, “Why not include such things?” Well, person in the back, what if the user decides to switch themes, even to another of yours? They would lose all of that information and have to figure out how to get it back. The option is unnecessary, would make the code overly complicated, and would cause trouble when the user switches themes. Include only options that alter functionality that is unique to your theme; otherwise it’s better suited to a plugin.

(22)

Developing WordPress Locally With MAMP

Ryan Olson

Local development refers to the process of building a website or Web application from the comfort of a virtual server, and not needing to be connected to the Internet in order to run PHP and MySQL or even to test a contact form. One of the most annoying parts of development, at least for me, is the constant cycle of edit, save, upload and refresh, which, depending on bandwidth and traffic, can turn a menial task into a nightmare.

With application platforms such as WordPress, which require a server back end to work, you would normally be constrained to develop on a live server, with the headaches that go along with that. MAMP and its Windows

counterpart, WAMP, are tools that allow you to locally develop applications that require a server on the back end.

!e Local Server

MAMP, which stands for Macintosh, Apache, MySQL and PHP, is an

application that allows you to install a local server-type environment in order to construct websites that would normally require you be on a live server somewhere.

(23)

Ever opened a contact form in a browser from your desktop and wondered why it doesn’t work? The server-side components cannot operate without (in this case) the PHP back end, and this is where MAMP comes in. By installing this application, we can have a virtual server locally as our

development sandbox. It is worth noting, from a portability standpoint, that this component can be run only from your desktop environment and cannot be installed on a USB drive. With that all settled, let’s get to it.

In order to be able to work with MAMP, we must first obtain it. So, head over to the project page and download the disc image. Double-click to begin the installation, and you will be presented with a choice:

Both MAMP and MAMP Pro come in the same download. You need to install only one, and for most scenarios, MAMP is more than adequate. The pro version costs $59.00 USD and offers more options, and you can compare the two versions for yourself.

Drag the MAMP folder onto the “Application” shortcut, and the installation will be underway. Once it’s completed, feel free to eject the disc image.

Open up your “Applications” folder, and locate the new MAMP directory.

Inside you’ll find MAMP.app, so — you guessed it — open it up. The program should start right away and open up your default browser, pointing to the start page. Congratulations, you now have a local server!

(24)

MAMP and MAMP Pro are on the installation disc image.

Preferences

From the main MAMP app screen, you will notice a “Preferences” button.

Feel free to click on it to view the few options available.

(25)

The MAMP app.

1. START/STOP

From here, you have the option to tell MAMP when to start and stop the servers. If you choose to not start the servers automatically, then you will need to explicitly tell them to run each time you open the app. You may also set your home page, which defaults to the MAMP start screen, giving you quick access to phpMyAdmin; but you may set it to something like a

WordPress directory.

(26)

Configuring the server.

2. PORTS

In the “Ports” tab, the default Apache port will usually be 8888, and the default MySQL port will be 8889. I, for one, do not change these because they do not interfere with any of my other settings and do not require me to enter my password every time I start and stop the servers.

(27)

You must include the port number in your URL this way; so, it would be localhost:8888/. To avoid this, you could change the ports to what general Web servers operate on: ports 80 and 3306. This will allow your URL to simply be localhost/; but you will most likely need to enter your password when switching the servers on and off. Another factor to consider is whether you are installing WordPress “multisite”; if you are, then you are required to set the ports to the default Apache and SQL ports of 80 and 3306, respectively.

Setting up MAMP ports.

(28)

3. PHP

The “PHP” tab allows you to choose which version of PHP to run in the set- up. It will default to 5.3, and I do not change this because most applications I run either require PHP 5.3 or do not care. Just know that this option is

available if you need it to run something such as legacy software.

Setting up the MAMP PHP version.

(29)

4. APACHE

The “Apache” tab is one that I like to mess with, to change the document root directory. The root is where all of your websites and directories will be stored and accessed by MAMP, and it defaults to /Applications/MAMP/

htdocs, which I find annoying to get to. So, I change mine to my sites folder. From the MAMP app window, click on “Preferences,” then on

“Apache.” You can click “Select” and then set the installation to use the location of your choice for your websites. Again, I set mine to the sites folder for easier access.

Setting up MAMP Apache.

(30)

Installing WordPress

Now it is time to install WordPress. Head to the WordPress website and download the latest version, 3.2 as of this writing. Unzip the folder, and then simply drag it to your sites folder, (or wherever you chose to set the

document root for MAMP). WordPress requires PHP and MySQL to operate, which is why we needed MAMP to develop locally; so, we now need need to make a database. Fear not: it is simple!

Open the MAMP start page — you can access it via the button in the main app — and click on “phpMyAdmin” in the top menu. Creating a new

database is as simple as typing a name in the field and hitting the “Create”

button. You can see below that I am creating a new database aptly named

“wordpress.” Once that’s done, feel free to close phpMyAdmin, and navigate to the WordPress directory in your document root.

(31)

Simply type a name for the database, and hit “Create.”

BASIC CONFIGURATION

Find the file named wp-config-sample.php, and open it in your favorite text editor. We have to configure a few settings. The default values for MAMP installations make this really easy to fill out, so follow the table below to see what to type where:

(32)

Variable Value DB_NAME wordpress DB_USER root

DB_PASSWORD root

Change the values of the variables to match the table above.

You should not need to alter anything else in this file, at least for now. You could add in the unique keys and salts, but I recommend doing that once you move the website into production.

Save and close wp-config-sample.php. We’re nearly done. Rename this file to wp-config.php — removing the -sample — and we are ready to complete the installation. You should now be able to point your browser to http://

localhost:8888/wordpress and see the WordPress installation screen.

Enter in your basic data and install the app. You are now ready to log into the admin section and get going!

(33)

Enter your information… but choose a stronger password.

(34)

Permalinks

Always follow WordPress’ permalink structure. In order for you to get these

“pretty URLs,” Apache will need mod_rewrite to update your .htaccess file, so let’s make sure that is set up.

The file we have to edit is httpd.conf, and you can find it in Applications → MAMP → conf → apache → /. Open this file, and search for a line like this:

LoadModule rewrite_module modules/mod_rewrite.so

Note that a hash (#) may or may not be in front of it. The hash indicates a comment, and if you see it, you must remove it to allow the mod_rewrite module to load. If the line is not commented out, then congratulations: you are already done! Close the file, and permalinks should now work in your local installation.

THE FINAL COUNTDOWN

By now, a local server set up with WordPress should be installed and running. The remaining steps are both short and crucial to sharing your creation with the Internet. All that remains is to transfer your local

accomplishments to a global environment by moving both our WordPress files and our content. So, let’s finish this up!

Going Live

The time has finally arrived. So, how do you bring your WordPress creation to the live server? Well, we have two options.

(35)

JUST GRAB THE CONTENT

A sometimes simpler way, with only a few steps, is to just grab all of your content. This is easiest if WordPress is already installed and you just need to import your theme and content. To do this, head to the admin dashboard, to the “Tools” section in the sidebar. Click on “Export,” and choose “All

content.” This will export a file that you can then import into your new installation.

Exporting WordPress content.

(36)

You can now upload your WordPress theme files to the live location. Head to the “Tools” section of the dashboard again, and choose “Import.” Simply point to the file that you just exported, and bring in your content.

BRINGING IN EVERYTHING

I use this method if I have done everything locally from the ground up. I’ll upload my entire local WordPress directory (in this case, http://

localhost:8888/wordpress) to the live server and then grab the database file and transfer that from local to live as well.

Because you could certainly build nearly the entire website in your development environment, bear in mind that WordPress uses absolute paths for URLs. So, every image and link will be prepended with http://

localhost:8888/ (depending on your set-up). We need a way to alter this to fit the live website. We have a few options.

1. EXPORT, SEARCH AND REPLACE

Using this method, we export our local database as a text file and run a

“Find and replace” on the text to replace all occurrences of the localhost URL with the production URL.

Begin by opening phpMyAdmin and clicking on your WordPress database on the left. Click on the “Export” tab in the top menu, and be sure to choose

“Select all” when choosing which tables to export. At the bottom, check the box to “Save as file,” and then hit “Go.” Open the resulting file in your

favorite text editor, and simply run a “Find and replace” to replace all instances of http://localhost:8888/wordpress with http://

www.YOUR_SITE_URL.com.

(37)

Exporting the WordPress database (click image for full-size view).

Save the edited file, and visit phpMyAdmin on your live server. Again, click on your WordPress database, and this time choose the “Import” option from the top menu, and browse for your newly edited file.

Once it successfully imports, upload your WordPress directory to the live server. If WordPress is already installed, simply upload your theme, any plugins you have installed locally and the contents of your wp-content/

uploads folder; or else, upload the entire local directory to your live

website’s root. Once that’s uploaded, be sure you can log into wp-admin, and browse around to make sure everything made it in. Update your permalink’s structure to something friendlier, and you are off!

(38)

2. USING SQL QUERIES

A second way to alter URL paths is to first bring everything into the live server version, and then use a few SQL queries to find and replace the necessary strings. Open phpMyAdmin on your local server, and export the database, again making sure to select all tables and to save it as a file. Go to your live server, and import the .sql file that you just saved. In the top menu, click on the tab for “SQL,” whereupon you will see a text area. You will need to enter some query syntax; be sure to replace the URLs in these code

fragments with the ones that pertain to your set-up — namely, the localhost’s path and the URL of your new live website.

Running SQL queries to update the URL paths (click image for full-size view).

(39)

Replacing WordPress’ base URL path:

UPDATE wp_options SET option_value = replace(option_value, 'http://

localhost:8888/wordpress ', '') WHERE option_name = 'home' OR option_name = 'siteurl';

Update the GUID that controls WordPress’ translating paths and post locations:

UPDATE wp_posts SET guid = REPLACE (guid, 'http://localhost:8888/

wordpress ', '');

Update the URL paths in the content:

UPDATE wp_posts SET post_content = REPLACE (post_content, 'http://

localhost:8888/wordpress ', '');

Update the URLs in the meta data of posts, such as attachments:

UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'http://

localhost:8888/wordpress ','');

Final !oughts

We have managed to install MAMP to set up a local server sandbox to develop in, and we’ve configured and installed a WordPress platform to develop in, saving the need for purely online development tactics.

I hope this has given you some insight into setting up a local environment to work with WordPress. Keep in mind that this is just scratching the surface;

WordPress is versatile. Now that we have this faster new way to develop, the next time we’ll get into some custom WordPress configurations.

(40)

HELPFUL LINKS

You may be interested in these related resources:

• “MAMP vs. MAMP Pro”

A chart comparing the two versions of MAMP.

• MAMP Documentation

• “Installing WordPress”

The walkthrough to install WordPress.

• “13 Useful WordPress SQL Queries You Wish You Knew Earlier”

A few SQL queries to aid with your WordPress development.

• “WordPress MultiSite with Subdomains on MAMP”

3-step tutorial on setting up subdomains with WordPress on MAMP.

(41)

!e Developer’s Guide To Conflict-Free JavaScript And CSS In WordPress

Peter Wilson

Imagine you’re playing the latest hash-tag game on Twitter when you see this friendly tweet:

You might want to check your #WP site. It includes two copies of jQuery.

Nothing’s broken, but loading time will be slower.

You check your source code, and sure enough you see this:

<script  src="/wp-­‐includes/js/jquery/jquery.js?ver=1.6.1"  type="text/

javascript"></script>

<script  src="/wp-­‐content/plugins/some-­‐plugin/jquery.js"></script>

WHAT WENT WRONG?

The first copy of jQuery is included the WordPress way, while some- plugin includes jQuery as you would on a static HTML page.

A number of JavaScript frameworks are included in WordPress by default, including:

• Scriptaculous,

• jQuery (running in noConflict mode),

• the jQuery UI core and selected widgets,

• Prototype.

(42)

A complete list can be found in the Codex. On the same page are instructions for using jQuery in noConflict mode.

AVOIDING THE PROBLEM

WordPress includes these libraries so that plugin and theme authors can avoid this problem by using the wp_register_script and wp_enqueue_script PHP functions to include JavaScript in the HTML.

Registering a file alone doesn’t do anything to the output of your HTML; it only adds the file to WordPress’s list of known scripts. As you’ll see in the next section, we register files early on in a theme or plugin where we can keep track of versioning information.

To output the file to the HTML, you need to enqueue the file. Once you’ve done this, WordPress will add the required script tag to the header or footer of the outputted page. More details are provided later in this article.

(43)

Registering a file requires more complex code than enqueueing the files; so, quickly parsing the file is harder when you’re reviewing your code.

Enqueueing the file is far simpler, and you can easily parse how the HTML is being affected.

For these techniques to work, the theme’s header.php file must include the line <?php wp_head(); ?> just before the </head> tag, and the

footer.php file must include the line <?php wp_footer(); ?> just before the </body> tag.

Registering JavaScript

Before registering your JavaScript, you’ll need to decide on a few additional items:

• the file’s handle (i.e. the name by which WordPress will know the file);

• other scripts that the file depends on (jQuery, for example);

• the version number (optional);

• where the file will appear in the HTML (the header or footer).

This article refers to building a theme, but the tips apply equally to building a plugin.

EXAMPLES

We’ll use two JavaScript files to illustrate the power of the functions:

The first is base.js, which is a toolkit of functions used in our example website.

(44)

function  makeRed(selector){

var  $  =  jQuery;  //enable  $  alias  within  this  scope $(function(){

$(selector).css('color','red');

});

}

The base.js file relies on jQuery, so jQuery can be considered a dependency.

This is the first version of the file, version 1.0.0, and there is no reason to run this file in the HTML header.

The second file, custom.js, is used to add the JavaScript goodness to our website.

makeRed('*');

This custom.js file calls a function in base.js, so base.js is a dependency.

Like base.js, custom.js is version 1.0.0 and can be run in the HTML footer.

The custom.js file also indirectly relies on jQuery. But in this case, base.js could be edited to be self-contained or to rely on another framework. There is no need for jQuery to be listed as a dependency of custom.js.

It’s now simply a matter of registering your JavaScript using the function wp_register_script. This takes the following arguments:

• $handle A string

• $source A string

• $dependancies An array (optional)

(45)

• $version

A string (optional)

• $in_footer

True/false (optional, default is false)

When registering scripts, it is best to use the init hook and to register them all at once.

To register the scripts in our example, add the following to the theme’s functions.php file:

function  mytheme_register_scripts()  { //base.js  –  dependent  on  jQuery wp_register_script(

'theme-­‐base',  //handle

'/wp-­‐content/themes/my-­‐theme/base.js',  //source array('jquery'),  //dependencies

'1.0.0',  //version true  //run  in  footer );

 

//custom.js  –  dependent  on  base.js wp_register_script(

'theme-­‐custom',

'/wp-­‐content/themes/my-­‐theme/custom.js', array('theme-­‐base'),

'1.0.0', TRUE );

}

add_action('init',  'mytheme_register_scripts');

There is no need to register jQuery, because WordPress already has. Re- registering it could lead to problems.

(46)

YOU HAVE ACHIEVED NOTHING!

All of this registering JavaScript files the WordPress way has, so far, achieved nothing. Nothing will be outputted to your HTML files.

To get WordPress to output the relevant HTML, we need to enqueue our files. Unlike the relatively long-winded commands required to register the functions, this is a very simple process.

Outpu"ing the JavaScript HTML

Adding the <script> tags to your HTML is done with the

wp_enqueue_script function. Once a script is registered, it takes one argument, the file’s handle.

Adding JavaScript to the HTML is done in the wp_print_scripts hook with the following code:

function  mytheme_enqueue_scripts(){

if  (!is_admin()):

wp_enqueue_script('theme-­‐custom');  //custom.js endif;  //!is_admin

}

add_action('wp_print_scripts',  'mytheme_enqueue_scripts');

Of our two registered JavaScript files (base.js and custom.js), only the

second adds JavaScript functionality to the website. Without the second file, there is no need to add the first.

Having enqueued custom.js for output to the HTML, WordPress will figure out that it depends on base.js being present and that base.js, in turn, requires jQuery. The resulting HTML is:

(47)

<script  src="/wp-­‐includes/js/jquery/jquery.js?ver=1.6.1"  type="text/

javascript"></script>

<script  src="/wp-­‐content/themes/my-­‐theme/base.js?ver=1.0.0"  type="text/

javascript"></script>

<script  src="/wp-­‐content/themes/my-­‐theme/custom.js?ver=1.0.0"  type="text/

javascript"></script>

Registering Style Sheets

Both of the functions for adding JavaScript to our HTML have sister PHP functions for adding style sheets to the HTML: wp_register_style and wp_enqueue_style.

As with the JavaScript example, we’ll use a couple of CSS files throughout this article, employing the mobile-first methodology for responsive Web design.

The mobile.css file is the CSS for building the mobile version of the website.

It has no dependencies. The desktop.css file is the CSS that is loaded for desktop devices only. The desktop version builds on the mobile version, so mobile.css is a dependency.

Once you’ve decided on version numbers, dependencies and media types, it’s time to register your style sheets using the wp_register_style function. This function takes the following arguments:

• $handle A string

• $source A string

• $dependancies

An array (optional, default is none)

(48)

• $version

A string (optional, the default is the current WordPress version number)

• $media_type

A string (optional, the default is all)

Again, registering your style sheets using the init action is best. To your theme’s functions.php, you would add this:

function  mytheme_register_styles(){

//mobile.css  for  all  devices wp_register_style(

'theme-­‐mobile',  //handle

'/wp-­‐content/themes/my-­‐theme/mobile.css',  //source null,  //no  dependencies

'1.0.0'  //version );

 

//desktop.css  for  big-­‐screen  browsers wp_register_style(

'theme-­‐desktop',

'/wp-­‐content/themes/my-­‐theme/desktop.css', array('theme-­‐mobile'),

'1.0.0',

'only  screen  and  (min-­‐width  :  960px)'  //media  type );

 

/*  *keep  reading*  */

}

add_action('init',  'mytheme_register_styles');

We have used CSS3 media queries to prevent mobile browsers from

parsing our desktop style sheet. But Internet Explorer versions 8 and below do not understand CSS3 media queries and so will not parse the desktop

(49)

IE8 is only two years old, so we should support its users with conditional comments.

CONDITIONAL COMMENTS

When registering CSS using the register and enqueue functions, conditional comments are a little more complex. WordPress uses the object

$wp_styles to store registered style sheets.

To wrap your file in conditional comments, add extra information to this object.

For Internet Explorer 8 and below, excluding mobile IE, we need to register another copy of our desktop style sheet (using the media type all) and wrap it in conditional comments.

In the code sample above, /* *keep reading* */ would be replaced with the following:

global  $wp_styles;

wp_register_style(

'theme-­‐desktop-­‐ie',

'/wp-­‐content/themes/my-­‐theme/desktop.css', array('theme-­‐mobile'),

'1.0.0' );

 

$wp_styles-­‐>add_data(

'theme-­‐desktop-­‐ie',  //handle

'conditional',    //is  a  conditional  comment

'!(IEMobile)&(lte  IE  8)'  //the  conditional  comment );

(50)

Unfortunately, there is no equivalent for wrapping JavaScript files in

conditional comments, presumably due to the concatenation of JavaScript in the admin section.

If you need to wrap a JavaScript file in conditional comments, you will need to add it to header.php or footer.php in the theme. Alternatively, you could use the wp_head or wp_footer hooks.

Outpu"ing !e Style Sheet HTML

Outputting the style sheet HTML is very similar to outputting the JavaScript HTML. We use the enqueue function and run it on the wp_print_styles hook.

In our example, we could get away with telling WordPress to queue only the style sheets that have the handles theme-desktop and theme-

desktop-ie. WordPress would then output the mobile/all media version.

However, both style sheets apply styles to the website beyond a basic reset: mobile.css builds the website for mobile phones, and desktop.css builds on top of that. If it does something and I’ve registered it, then I should enqueue it. It helps to keep track of what’s going on.

Here is the code to output the CSS to the HTML:

function  mytheme_enqueue_styles(){

if  (!is_admin()):

wp_enqueue_style('theme-­‐mobile');  //mobile.css wp_enqueue_style('theme-­‐desktop');  //desktop.css

wp_enqueue_style('theme-­‐desktop-­‐ie');  //desktop.css  lte  ie8 endif;  //!is_admin

}

(51)

What’s !e Point?

You may be wondering what the point is of going through all of this extra effort when we could just output our JavaScript and style sheets in the theme’s header.php or using the wp_head hook.

In the case of CSS in a standalone theme, it’s a valid point. It’s extra work without much of a payoff.

But with JavaScript, it helps to prevent clashes between plugins and themes when each uses a different version of a JavaScript framework. It also makes page-loading times as fast as possible by avoiding file duplication.

WORDPRESS FRAMEWORKS

This group of functions can be most helpful when using a framework for theming. We’ve built a framework to speed up our production of websites in our agency.

As with most agencies, we have internal conventions for naming JavaScript and CSS files.

When we create a bespoke WordPress theme for a client, we develop it as a child theme of our framework. In the framework itself, we register a number of JavaScript and CSS files in accordance with our naming convention.

In the child theme, we then simply enqueue files to output the HTML.

(52)

function  clienttheme_enqueue_css()  { if  (!is_admin()):

wp_enqueue_style('theme-­‐mobile');

wp_enqueue_style('theme-­‐desktop');

wp_enqueue_style('theme-­‐desktop-­‐ie');

endif;  //!is_admin }

add_action('wp_print_styles',  'clienttheme_enqueue_css');

 

function  clienttheme_enqueue_js()  { if  (!is_admin()):

wp_enqueue_script('theme-­‐custom');

endif;  //!is_admin }

add_action('wp_print_scripts',  'clienttheme_enqueue_js');

Adding CSS and JavaScript to our themes the WordPress way enables us to keep track of exactly what’s going on at a glance.

A Slight Limitation

If you use a JavaScript framework in your theme or plugin, then you’re stuck with the version that ships with the current version of WordPress, which sometimes falls a version or two behind the latest official release of the framework. (Upgrading to a newer version of the framework is technically possible, but this could cause problems with other themes or plugins that expect the version that ships with WordPress, so I’ve omitted this

information from this chapter.)

While this prevents you from using any new features of the framework that were added after the version included in WordPress, the advantage is that all theme and plugin authors know which version of the framework to expect.

(53)

A Single Point Of Registration

Register your styles and scripts in a single block of code, so that when you update a file, you will be able to go back and update the version number easily.

If you use different code in different parts of the website, you can wrap the logic around the enqueue scripts.

If, say, your archive pages use different JavaScript than the rest of the website, then you might register three files:

• base JavaScript (registered as theme-base),

• archive JavaScript (registered as theme-archive),

• general JavaScript (registered as theme-general).

Again, the base JavaScript adds nothing to the website. Rather, it is a group of default functions that the other two files rely on. You could then enqueue the files using the following code:

function  mytheme_enqueue_js(){

if  (is_archive())  {

wp_enqueue_script('theme-­‐archive');

}

elseif  (!is_admin())  {

wp_enqueue_script('theme-­‐general');

} }

add_action('wp_print_scripts',  'mytheme_enqueue_js');

Using !e Google AJAX CDN

(54)

While using JavaScript the WordPress way will save you the problem of common libraries conflicting with each other, you might prefer to serve these libraries from Google’s server rather than your own.

Using Jason Penny’s Use Google Libraries plugin is the easiest way to do this. The plugin automatically keeps jQuery in noConflict mode.

Pu"ing It All Together

Once you’ve started registering and outputting your scripts and styles the WordPress way, you will find that managing these files becomes a series of logical steps:

1. Registration to manage:

• version numbers,

• file dependencies,

• media types for CSS,

• code placement for JavaScript (header or footer);

2. Enqueue/output files to HTML:

• logic targeting output to specific WordPress pages,

• WordPress automating dependencies.

Eliminating potential JavaScript conflicts from your WordPress theme or plugin frees you to get on with more important things, such as following up on sales leads or getting back to that hash-tag game that was so rudely interrupted.

(55)

Interacting With !e WordPress Database

Daniel Pataki

While you already use many functions in WordPress to communicate with the database, there is an easy and safe way to do this directly, using the

$wpdb class. Built on the great ezSQL class by Justin Vincent, $wpdb enables you to address queries to any table in your database, and it also helps you handle the returned data. Because this functionality is built into WordPress, there is no need to open a separate database connection (in which case, you would be duplicating code), and there is no need to perform hacks such as modifying a result set after it has been queried.

The $wpdb class modularizes and automates a lot of database-related tasks.

(56)

In this chapter, I will show you how to get started with the $wpdb class, how to retrieve data from your WordPress database and how to run more

advanced queries that update or delete something in the database. The techniques here will remove some of the constraints that you run into with functions such as get_posts() and wp_list_categories(), allowing you to tailor queries to your particular needs. This method can also make your website more efficient by getting only the data that you need — nothing more, nothing less.

Ge"ing Started

If you know how MySQL or similar languages work, then you will be right at home with this class, and you will need to keep only a small number of function names in mind. The basic usage of this class can be best

understood through an example. So let’s query our database for the IDs and titles of the four most recent posts, ordered by comment count (in

descending order).

<?php

$posts  =  $wpdb-­‐>get_results("SELECT  ID,  post_title  FROM  $wpdb-­‐>posts   WHERE  post_status  =  'publish'

AND  post_type='post'  ORDER  BY  comment_count  DESC  LIMIT  0,4")

?>

As you can see, this is a basic SQL query, with some PHP wrapped around it. The $wpdb class contains a method (a method is a special name for functions that are inside classes), named get_results(), which will not only fetch your results but put them in a convenient object.

You might have noticed that, instead of using wp_posts for the table’s name, I have used $wpdb->posts, which is a helper to access your core WordPress tables. More on why to use these later.

(57)

The $results object now contains your data in the following format:

Retrieving Results From !e Database

If you want to retrieve some information from the database, you can use one of four helper functions to structure the data.

Array (

[0]  =>  stdClass  Object (

[ID]  =>  6

[post_title]  =>  The  Male  Angler  Fish  Gets  Completely  Screwed )

 

[1]  =>  stdClass  Object (

[ID]  =>  25

[post_title]  =>  10  Truly  Amazing  Icon  Sets  From  Germany )

 

[2]  =>  stdClass  Object (

[ID]  =>  37

[post_title]  =>  Elderberry  Is  Awesome )

 

[3]  =>  stdClass  Object (

[ID]  =>  60

[post_title]  =>  Gathering  Resources  and  Inspiration  With  Evernote )

  )

(58)

GET_RESULTS()

This is the function that we looked at earlier. It is best for when you need two-dimensional data (multiple rows and columns). It converts the data into an array that contains separate objects for each row.

<?php

$posts = $wpdb->get_results("SELECT ID, post_title FROM wp_posts WHERE post_status = 'future' AND post_type='post' ORDER BY post_date ASC LIMIT 0,4")

// Echo the title of the first scheduled post echo $posts[0]->post_title;

?>

GET_ROW

When you need to find only one particular row in the database (for example, the post with the most comments), you can use get_row(). It pulls the data into a one-dimensional object.

GET_COL

This method is much the same as get_row(), but instead of grabbing a single row of results, it gets a single column. This is helpful if you would like to retrieve the IDs of only the top 10 most commented posts. Like

get_row(), it stores your results in a one-dimensional object.

<?php

$posts = $wpdb->get_row("SELECT ID, post_title FROM wp_posts WHERE post_status = 'publish'

AND post_type='post' ORDER BY comment_count DESC LIMIT 0,1")

// Echo the title of the most commented post echo $posts->post_title;

?>

(59)

<?php

$posts = $wpdb->get_col("SELECT ID FROM wp_posts WHERE post_status

= 'publish'

AND post_type='post' ORDER BY comment_count DESC LIMIT 0,10")

// Echo the ID of the 4th most commented post echo $posts[3]->ID;

?>

GET_VAR

In many cases, you will need only one value from the database; for example, the email address of one of your users. In this case, you can use get_var to retrieve it as a simple value. The value’s data type will be the same as its type in the database (i.e. integers will be integers, strings will be strings).

<?php

$email = $wpdb->get_var("SELECT user_email FROM wp_users WHERE user_login = 'danielpataki' ")

// Echo the user's email address echo $email;

?>

Inserting Into !e Database

To perform an insert, we can use the insert method:

$wpdb->insert( $table, $data, $format);

(60)

This method takes three arguments. The first specifies the name of the table into which you are inserting the data. The second argument is an array that contains the columns and their respective values, as key-value pairs. The third parameter specifies the data type of your values, in the order you have given them. Here’s an example:

<?php

$wpdb->insert($wpdb->usermeta, array("user_id" => 1, "meta_key" =>

"awesome_factor", "meta_value" => 10), array("%d", %s", "%d"));

// Equivalent to:

// INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, "awesome_factor", 10);

?>

If you’re used to writing out your inserts, this may seem unwieldy at first, but it actually gives you a lot of flexibility because it uses arrays as inputs.

Specifying the format is optional; all values are treated as strings by default, but including this in the method is a good practice. The three values you can use are %s for strings, %d for decimal numbers and %f for floats.

Updating Your Data

By now, you won’t be surprised to hear that we also have a helper method to update our data — shockingly, called update().

Its use resembles what we saw above; but to handle the where clause of our update, it needs two extra parameters.

$wpdb->update( $table, $data, $where, $format = null, $where_format

= null );

(61)

The $table, $data and $format parameters should be familiar to you;

they are the same as before. Using the $where parameter, we can specify the conditions of the update. It should be an array in the form of column- value pairs. If you specify multiple parameters, then they will be joined with AND logic. The $where_format is just like $format: it specifies the format of the values in the $where parameter.

$wpdb->update( $wpdb->posts, array("post_title" => "Modified Post Title"), array("ID" => 5), array("%s"), array("%d") );

Other Queries

While the helpers above are great, sometimes performing different or more complex queries than the helpers allow is necessary. If you need to perform an update with a complex where clause containing multiple AND/OR logic, then you won’t be able to use the update() method. If you wanted to do something like delete a row or set a connection character set, then you would need to use the “general” query() method, which let’s you perform any sort of query.

$wpdb->query("DELETE FROM wp_usermeta WHERE meta_key = 'first_login' OR meta_key = 'security_key' ");

Protection And Validation

I hope I don’t have to tell you how important it is to make sure that your data is safe and that your database can’t be tampered with! Data validation is a bit beyond the scope of this article, but do take a look at what the

WordPress Codex has to say about “Data Validation” at some point.

(62)

In addition to validating, you will need to escape all queries. Even if you are not familiar with SQL injection attacks, still use this method and then read up on it later, because it is critical.The good news is that if you use any of the helper functions, then you don’t need to do anything: the query is escaped for you. If you use the query() method, however, you will need to escape manually, using the prepare() method.

$sql = $wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] );

To make this a bit more digestible, let’s rewrite this basic format a bit.

$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id,

meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 )

$wpdb->query($sql);

As you can see, this is not that scary. Instead of adding the actual values where you usually would, you enter the type of data, and then you add the actual data as subsequent parameters.

Class Variables And Other Methods

Apart from these excellent methods, there are quite a few other functions and variables to make your life easier.

I’ll show you some of the most common ones, but please do look at the WordPress Codex page linked to above for a full list of everything that

$wpdb has to offer.

INSERT_ID()

Whenever you insert something into a table, you will very likely have an auto-incrementing ID in there. To find the value of the most recent insert

(63)

$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id,

meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 )

$wpdb->query($sql);

$meta_id = $wpdb->insert_id;

NUM_ROWS()

If you’ve performed a query in your script, then this variable will return the number of results of your last query. This is great for post counts, comment counts and so on.

TABLE NAMES

All the core table names are stored in variables whose names are exactly the same as their core table equivalent. The name of your posts table

(probably wp_posts) would be stored in the $posts variable, so you could output it by using $wpdb->posts.

We use this because we are allowed to choose a prefix for our WordPress tables. While most people use the default wp, some users want or need a custom one. For the sake of flexibility, this prefix is not hardcoded, so if you are writing a plugin and use wp_postmeta in a query instead of $wpdb->

postmeta, your code will not work on some websites.

If you want to get data from a non-core WordPress table, no special variable will be available for it. In this case, you can just write the table’s name as usual.

(64)

ERROR HANDLING

By calling the show_errors() or hide_errors() methods, you can turn error-reporting on or off (it’s off by default) to get some more info about what’s going on. Either way, you can also use the print_error() method to print the errors for the latest query.

$wpdb->show_errors();

$wpdb->query("DELETE FROM wp_posts WHERE post_id = 554 ");

// When run, because show_errors() is set, the error message will tell you that the "post_id" field is an unknown

// field in this table (since the correct field is ID)

Building Some Basic Tracking With Our New $wpdb Knowledge

If you’re new to all of this, you probably get what I’m going on about but may be finding it hard to implement. So, let’s take the example of a simple

WordPress tracking plugin that I made for a website.

For simplicity’s sake, I won’t describe every detail of the plugin. I’ll just show the database’s structure and some queries.

OUR TABLE’S STRUCTURE

To keep track of ad clicks and impressions, I created a table; let’s call it

“tracking.” This table records user actions in real time. Each impression and click is recorded in its own row in the following structure:

• ID

The auto-incremented ID.

(65)

• time

The date and time that the action occurred.

• deal_id

The ID of the deal that is connected to the action (i.e. the ad that was clicked or viewed).

• action

The type of action (i.e. click or impression).

• action_url

The page on which the action was initiated.

• user_id

If the user is logged in, their ID.

• user_ip

The IP of the user, used to weed out any naughty business.

This table will get pretty big pretty fast, so it is aggregated into daily

statistics and flushed periodically. But let’s just work with this one table for now.

Inserting Data Into Our Tables

When a user clicks an ad, it is detected, and the information that we need is sent to our script in the form of a $_POST array, with the following data:

Références

Documents relatifs

The Mark IV Clustered Display System (formerly the CO:77 Information Display System) is a direct replace- ment for the IBM 3270 Information Display System and

BD-LETTER.LISP The book design specifications for the Letter Generic, Letter Screen, and Letter LGP2 document device types.. Various com- mands and environments used only by the

TEd it no longer causes interrupt characters (control-D, control-E, etc.) to be disabled outside of the TEdit process.. • TEdit menu operations no longer prevent the

This document specifies two DHCPv6 options [1] that allow SIP clients to locate a local SIP server that is to be used for all outbound SIP requests, a so-called outbound

(DHCP-for-IPv4) option that contains a list of domain names or IPv4 addresses that can be mapped to one or more Session Initiation Protocol (SIP) outbound proxy servers.. This

A Notification Subscription is a request by a Notification Subscriber to the IPP Printer to send Event Notifications to specified.. Notification Recipient(s) when an

An LSR that does not recognize a TLV type code carried in this object MUST reject the Path message using a PathErr with Error Code &#34;Unknown Attributes TLV&#34; and Error

A key parameter is the factor by which service providers want or need to multiply their IPv4 public address space, and the consequence is the number of subscribers sharing