don't sh** in the pool

Download Don't sh** in the Pool

If you can't read please download the document

Upload: chris-jean

Post on 16-Apr-2017

6.745 views

Category:

Technology


0 download

TRANSCRIPT

Don't Sh** in the Pool

How your code can ruin WordPress for others

Chris is a member of the iThemes.com team and is the lead developer of iThemes Builder. He stinks at writing his own bios and really dislikes writing in the third-person, so he'll just list some random things. Chris has 10 years of professional web development experience with three years spent with WordPress development. While he works with themes, he can't design an attractive site to save his life, so he focuses his efforts on coding, nitpicking on off-by-one-pixel issues, and working on new concepts. Chris thinks himself to be a nice guy, but he's really kind of a jerk.

Who Am I?

What Is This?

For WordPress, plugins, and themes to work well, they need to work together.

Very simple and valid looking solutions can quickly create compatibility problems with other plugins, with themes, and with WordPress itself.

People then talk about these amazing solutions that they've come up with to solve their problems.

Everyone starts using these solutions in all of their projects.

The world burns.

This presentation is a focus on the worst practices in WordPress development.

A study in how not to do certain things, why they are an issue, and how to avoid the problem.

What Is This, Really?

Who Is This Presentation For?

Developers that share code on the WordPress.org repositories.

Developers that sell plugins or themes.

Bloggers that blog about example solutions.

Writers of books and other tutorial documents that include code examples.

Basically, anyone that works with or talks about code.

Why Certain Developers Will Hate This Presentation

This presentation will not be nice.

This presentation may upset certain developers.

This presentation will call people out.

Not everyone will agree with me.

Why I Don't Care

These problems are real.

These problems are prolific.

These problems are wasting hundreds of hours of labor each week from debugging compatibility issues.

Developers need to be aware of the issues and fix them.

We'll start with a very popular practice, using wp_deregister_script to replace a WordPress core script with a newer/older/modified script.

wp_deregister_script('jquery');wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js');wp_enqueue_script('jquery');

Changing Core Scripts: The Example

Changing Core Scripts: The Problem

Since WordPress comes with specific scripts, developers should be able to look at the WordPress version to be able to know what version of a script will be run.

Changing the script can quickly cause solutions that rely on a specific version of a script to break.

Replacing a script is shifting the development difficulty from yourself to everyone else.

In other words, it is a prime example of selfish development.

Changing Core Scripts: The Solution

Never use wp_deregister_script unless it is solely for your own internal use. Even in these cases, don't use it unless you absolutely must or are just testing.

Learn to make your code adapt to different script versions rather than requiring every other developer to adapt their code to suit your needs.

Profit.

Directly Printing Scripts/Styles: The Example

Have you written this before?

echo '';

If so, you're doing it wrong.

Directly Printing Scripts/Styles: The Problem

In many ways, this problem is similar to the one where built-in scripts are modified.

Imagine that someone used the enqueues system to properly enqueue a script that you then directly added to the page output. Now, the script is loaded twice, potentially with different versions and features.

This quickly leads to compatibility conflicts.

Directly Printing Scripts/Styles: The Problem

The following are just a small sample of some of the plugins on the repo that have this issue (in 5pt):

1000eb, 123contactform-for-wordpress, 123linkit-affiliate-marketing-tool-mu-edition, 140follow, 17fav-bookmark-share, 1-bit-audio-player, 1-click-adsense, 1-click-retweetsharelike, 1-for-wordpress, 1g1g-music-bar, 1g-music-share, 1gwordpress, 271-update-to-quizzin-by-binny-v-a, 2-click-socialmedia-buttons, 2performant-product-importer, 2-way-micropay-monetize-3-ways, 360panoembed, 3b-meteo, 3damory-for-wordpress, 3d-pix, 3d-twitter-wall, 4xeagleeye-analyst, 5gig-concerts, 5mincom-video-suggestions, 7feeds-news-ticker, 7uploads, 99-doanloandmangager, 99-facebox-download, a9-siteinfo-generator, abdul-tag, abdul-tag-widget, abdul-wp-plugin, abstract-submission, abtest, ab-test-for-wordpress, accesible-blank, accordion-image-menu, accordion-the-wordpress-ajax-widget, acid-maintenance-mode-wp, ackuna-language-translation-plugin, acobot, acrostiche, acs-plugin-for-wordpress, activator, activecampaign, active-extra-fields, activehelper-livehelp, active-share-by-orangesoda, activity-life-stream, adbrite-integration, ad-buttons, adcaptcher, ad-code-manager, ad-codez-widget, adcrunch-quick-shortlinks-for-wordpress, addfeed-widget, add-flickr-photo-with-geo-tag, addfreestats, add-functions, add-google-plusone, add-google-plus-one-social-share-button, add-icons-to-sidebar-of-categories, add-icons-to-sidebar-of-categories-and-pages, addinto, add-link-to-facebook, addmarx, add-other-ads-now, addremove-form-outlines, addthis, addthis-button-for-post, addthischina, add-to-any-subscribe, add-to-footer, add-twitter-anywhere, addynamo-plugin, addynamo-widget, add-youtube, adfly-wordpress-plugin, ad-free-google-safe-search-for-schools, adgallery-slider, adherder, adicons, adicon-server-16x16, adlemons, ad-logger, admin-colour, admin-comment, adminer, admium, ads-by-cb, ads-by-country, adscaptcha, adsense-deluxe-revived, adsense-extreme, adsense-for-wordpress, adsense-google-widget, adsense-insert, adsense-manager, adsense-now, adsense-now-lite, adsense-now-redux, adsenseoptimizer, adsense-plugin, adsense-revenue-sharing, adsense-widget, adspeed-ad-server, ad-squares-widget, advanced-author-exposed, advanced-code-editor, advanced-custom-fields, advanced-custom-sort, advanced-events-registration, advanced-fancybox, advanced-permalinks, advanced-random-post, advanced-tagline, advanced-text-widget, advanced-twitter-profile-widget, advanced-twitter-widget, advanced-videobox, advanced-wordpress-theme-editor, advanced-youtube-widget, advertising-manager, adwit-banner-manager, ae-syntax, afc-flv-player, afc-google-map, afc-image-loop, affiliando-vergleichsrechner, affiliate-easel-for-amazon, affiliate-image-tracker, affiliate-link1, affiliate-link-cloaking, affiliate-product-optimizer, affiliatewire-quick-ignition, ag-custom-admin, age-confirmation, agenteasy-properties, agentrank, agent-storm, air-badge, air-conditioning-calculator, aitendant-for-wordpress, aixostats, ajax-campaign-monitor-forms, ajax-category-dropdown, ajax-category-posts-dropdown, ajaxcoderender, ajaxcomment, ajax-comment-page, ajax-comment-pager, ajax-comments, ajax-comments-spy, ajax-comments-wpmuified, ajax-contact, ajax-css-switcher, ajaxd-wordpress, ajax-easy-attendance-list, ajax-fancy-captcha, ajaxgallery, ajax-login, ajax-loginregister, ajax-login-widget, ajax-page-loader, ajax-page-loader-15, ajax-post-listing, ajax-random-post, ajax-random-posts, ajax-save-post, ajax-slide, ajax-spell-checker, ajax-tag-suggest, ajax-weather, ajaxy-search-form, akwplightbox, akwpuploader-alternative-wordpress-image-uploader, al3x-file-manager, alakhnors-post-thumb, albo-pretorio-on-line, alchemytagger, ald-openbrwindow, ald-openimagewindow, ald-transpose-email, a-lead-capture-contact-form-and-tab-button-by-awebvoicecom, alert-before-your-post, alexa-rank, alfie-the-productfeedtool-wp-plugin, alipay, all-category-seo-updater, allegrato, all-in-one-adsense-and-ypn, all-in-one-adsense-and-ypn-pro, all-in-one-cufon, all-in-one-event-calendar, all-in-one-facebook-pack, all-in-one-gallery, all-in-one-qype-suite, all-in-one-slideshow, all-in-one-social-network-buttons, all-in-one-video-pack, all-in-one-webmaster, all-new-blogroll, allopass, allow-php-in-posts-and-pages, all-social-fw-style-widget, allwebmenus-wordpress-menu-plugin, alo-easymail, al-quran-random, altos-connect, altos-toolbar, altpwa, amazon-affiliate-link-localizer, amazon-context-link-ads, amazon-contextual-lightbox, amazonify, amazonjs, amazon-link, amazon-mp3-widget, amazon-product-ads, amazon-search-widget, amazonsimpleadmin, amazon-smartlinks, amazon-widgets-shortcodes, amber-alert-nederland, amr-clearskys-availability-modification-for-27, amw-chat, amw-chat-fixed, analytics7-widget, anchor-link-effect, anetwork-widget, angular, aniga-gallery, animal-captcha, animated-banners, anmiated-twitter-bird, annonces, announcement, announcement-and-vertical-scroll-news, announcement-ticker-highlighter-scroller, anobii-wordpress-widget, anonimacao-ctdo, anon-posting, another-wordpress-classifieds-plugin, answerlinks, anti-captcha, anti-ie6-army, anti-plagiarism, anti-splog, anupraj-tell-friends, anyfeed-slideshow, anyfont, anynote, anywhere, apiki-wp-faq, apparatus, appointment-calendar, appstore, apptha-banner, apptha-slider-gallery, apture, aquotic-random-quote, arabic-word-of-the-day, arcres-booking-engine, are-paypal, arielbrailovsky-viralad, arkavis-games-sidebar, armenian-keyboard, arrowchat-wordpress-integration, article-directory, article-directory-script, articles-protection-plugin, askapache-debug-viewer, askapache-firefox-adsense, askapache-google-404, ask-question, asr-verify-code, asset-manager, associative-dictionary-widget, async-google-analytics, at-internet-analyzer-ii, at-internet-analyzer-nx, atma-links-automatic-linker-tool, atokens, a-to-z-category-listing, atpic, attributor-fairshare-plugin, audiencc, audiobar, audioboo-wp, audio-player, audio-player-oogiechetos, audio-tube, auktionsscroller-for-tradera-widget, austin-tech-events-calendar, author-advertising-pro, author-comment-replies, author-data, author-exposed, author-popup, author-tweets, auto-attachments, autoblog, auto-blogroll, auto-google-chrome-frame, auto-hide-menubar, auto-highslide, automated-editor, automatic-facebook-converter, autoping-norway, auto-poster, auto-post-images-api, autoptimize, autopublish, autoresponder-gwa, auto-shop, auto-tooltip, autotube, auto-youtube, avactis-shopping-cart-affiliate-widget, avantlink-wp, avramtar, awasete-yomitai-for-wordpress, aweber-footer-slideup, aweber-integration, aweber-web-form-widget, awesome-ads, awesome-authors, awesome-flickr-gallery-plugin, awesome-google-adsense, awsom-news-announcement, awsom-pixgallery, awstats-script, awstats-xtended-info, ayah-of-the-day, ayar-comment, ayar-tinymce-with-virtual-keyboard-and-burmese-datetime, ayar-unicode-combobox, ayar-unicode-converter, ayar-unicode-toolbar, ayar-webkit, ayar-web-kit, baap-mobile-version, babel, babelz, background-changer, backstory-for-wordpress, backtype-tweetcount, banckle-live-chat-for-wordpress, bandsintown, bangla-ajax-calendar, banner-ads, banner-aink, banner-design, banner-garden, bannerman, banner-manager, banner-slider, barnameha-roozmare, base16b-encoderdecoder, baseballnuke, baufinanzierung, baza-agentov, bbcode-shortcut, bbc-world-service-widget, bbpress-antispam, bbpress-ignore-user, bbpress-latest-discussion, bbpress-post-toolbar, bbpress-recaptcha, bbuinfo-blogblogs-user-info-plugin, bb-usage-stats, beacon-wordpress-plugin, beer-recipes, before-its-news-blogging-citizen-journalism-widget, before-its-news-featured-stories, before-its-news-health, before-its-news-lifestyle, before-its-news-mainstream, before-its-news-money, before-its-news-paranormal-news-widget, before-its-news-politics, before-its-news-sci-tech, before-its-news-self-sufficiency, behnevis-transliteration, belindes-bricks-box, belocal-plugin, benchmark-email-wordpress, benjamin-sterling-galleries, bensgigs, bens-translator, best-buy-products-plugin, best-google-adsense, best-google-plus-one-social-wordpress-plugin, best-social-share, betta-boxes-cms, better-comments-manager, better-extended-live-archive, better-file-editor, better-gallery2, better-search, better-seo-slugs, better-wordpress-syntax-based-on-geshi, bezahlcode-generator, bfv-widget-wp, bg-import, bib2html, bib3html, bible, bible-post, bibly, bibstweezfollowbutton, bibs-twitter-follow-button-reloaded, bic-media, bigbluebutton, big-cartel-wordpress-plugin, bilingual-linker, bing-maps-for-wordpress, bing-maps-widget, binlayerpress, biorhythm, bitacorascom, bitcoin-plus-miner, bitdefender-antispam-for-wordpress, bitlet-plugin, bits-on-the-run, bittads-for-wordpress, bizsugar-vote-button, bizsugar-voting-button, blackbox-debug-bar, blago-air-badge-clicktracker, blastchat, blaze-slide-show-for-wordpress, bl-countdown-timer, blindall-slideshow, blindx-slideshow, blindy-slideshow, blindz-slideshow, blippr, blippr-reviews, block-ie6, blog2widget, blogactivityshortcode, blog-activity-shortcode, blogarate-rating-widget, blog-demographics, bloggersbase-content-syndication-widget, blogger-to-wordpress-redirection, bloggy-till-wordpress, bloghint, blogmap-geolocation, blogmarking, blog-mechanics-theme-gallery, blogorola-wordpress-plugin, blog-quickly-shout, blogroll-google-cse, blog-search, blog-stats-by-w3counter, blog-tech-check, blogtext, blog-topics, blog-toplist, bluemelon-gallery, blue-smilies, bmlt-wordpress-satellite-plugin, bm-tweet-this, bns-twitter-follow-button, body-mass-index-calculator, bol, bolcom-partner-program-plugin, boo-boxfy, boo-boxfy-classic, bookcottages-availability-calendar, booking, bookingbug, booking-framework, booking-manager, bookings, bookjive-free-audio-books, bookmark-export, bookmarkify, bookmark-share-simple, bookx, boslideshow, boton-twittear, botproof-captcha-20, bottom-bar, bouncecc-blog-monetizer, bowob, boxer, bp-authnet, bpckeditor, bp-fbconnect, bp-labs, bp-member-map, bp-members-avatar-map, bp-member-widget, bp-translate, bp-tweet-button, bp-tweet-urls, bp-user-profile-map, bp-webcam-avatar, brainpop-uk-learning-video, branded-login-screen, brands-20, brinkin-banner-exchange, brog-indexor, brokerswebads, browser-bookmark, browser-specific-css, browser-window-stats, br-twitter-widget, bt-widget, bubblecast-video-plugin, buddypress-activity-stream-bar, buddypress-author-exposed, buddypress-classifieds, buddypress-comments-collapse-and-expand, buddypress-docs, buddypress-easy-albums-photos-video-and-music, buddypress-geo, buddypress-group-forum-extras, buddypress-group-plus, buddypress-group-wiki, buddypress-jquery-activity-stream-widget, buddypress-kaltura-media-component, buddypress-links, buddypress-mobile, buddypress-multilingual, buddypress-recaptcha, buddypress-share-it, buddypress-smf-import, buddystream, buffer-button, bug-library, bug-tracker, bulk-delete, bulk-me-now, bumpin-widget, buscape-wp-related-products, businesscard2-card, business-directory-plugin, buton-de-follow, buzrrcom-button-plugin, buzzom-badge-plugin, buzzsprout-podcasting, buzzthis, buzz-this-google-official-api-implementation, buzzvolume, buzzwords, buzzz-et, bwp-minify, bwp-polldaddy, bwp-recaptcha, bye-maridjan-seo, caccordin, cache-manifest-for-wordpress-themes, cackle, cacoo-for-wordpress, cafepress-widget, calculatorpro-calculators, calendar, calendar-archives, calendar-header-bar-image, calendar-plus, calendar-posts, calendar-press, callrail-phone-call-tracking, canalplan-ac, capsule-web2lead, captchaad, captcha-for-comment, captchathedog, captionbox, captionpix, carousel-free-video-gallery, carousel-gallery, carousel-gallery-jquery, carousel-video-gallery, cart66-lite, cartoline-on-line, cartpauj-pm, caspio-deploy2, catalog-page, categories4page, category-image, category-import, category-page-icons, category-seo-meta-tags, category-templates, category-templates-two, catfish-ad-manager, cawaii-admin, cbnet-ping-optimizer, cbnet-twitter-faves-display, cbnet-twitter-list-display, cbnet-twitter-profile-display, cbnet-twitter-search-display, cbnet-twitter-widget, cdn-sync-tool, cdnvote, cdokay-tv-youtube-video-gallery, cent2cent, cevhershare, cf7-calendar, cf-shopping-cart, chameleon-css, change-font-size, changeorg, chango-wordpress-plugin, chaos-video-embed, chap-secure-login, chartbeat, chat, chatbot-widget, chat-instantaneo, cheatsheet, checkfront-wp-booking, check-urlmalware, chess-by-blog, chess-game-viewer-control-panel, chikuncount, chimpexpress, chimppress, chinese-traditional-word-of-the-day, chinese-word-of-the-day, chitika-linx, chitika-premium, chitika-rpu-4-wordpress, choicecuts-image-juggler, christmas-countdown-clock, christmas-message, chromeframe-for-wordpress, church-admin, cigicigi-post-guest, cimy-user-extra-fields, cincopa-video-slideshow-photo-gallery-podcast-plugin, ck-and-syntaxhighlighter, ckeditor-for-wordpress, ckwnc, claptastic-clap-button, clean-contact, cleanprint-lt, cleditor-for-wordpress, cleeng, cleveritics-for-wordpress, click2refer-virtual-dictionary, clickbank-hop-ad, clickst, clicktale, clicktale-analytics, click-to-call-me, clipta-video-informer, clocky, clouds, cmf-ads-widget, cminus, cm-newsletter, cms, cmsify, cms-vote-up-social-cms-news-button, cnet-api-search, co-authors, code-block-enabler, codecolorer-tinymce-button, code-face, codelibs, codestyling-localization, coin-slider-4-wp, collabable, collapse-page-and-category-plugin, collapsible-archive-widget, collision-testimonials, colorcode, colorful-tag-widget, combo-slideshow, comicpress-manager, comment-contest, comment-emailer, commenters-info, comment-form-toolbar, comment-geo-maps, comment-quicktags, comment-reactor, comments-likes, comment-spam, comments-policy, comments-with-hypercommentscom, comment-toolbar, communityapi-single-signon, community-links-feed, communitypress, community-submitted-news, community-yard-sale, comparepress, compartilhe-no-orkut, compartir-en-tuenti, compassion-widget, competition-manager, complete-stats, complexlife, compras-en-linea, computerboeknl-widget, conditional-digg-this-badge, conduit-banner-selector, constant-footer, contactbuddy-by-pluginbuddycom, contact-commenter, contact-commenters, contactform, contact-form-captcha, contact-form-with-captcha, contact-form-wordpress, contact-me, contact-me-widget, contact-us, contact-wp, contentboxes, contentpro, content-security-policy, contentshare, content-text-slider-on-post, content-types-wordpress-plugin, contextual-ppc-revenue-by-advtisecom, contextual-related-posts, contexture-page-security, continuous-announcement-scroller, contus-hd-flv-player, contus-vblog, contus-video-comments, contus-video-galleryversion-10, conversation-starter, conversion-popup-survey, conveythis-language-translation-plugin, cool-contact-form, cooleye, cool-facebook-like-box, cool-fade-popup, cool-video-gallery, cool-weather, copa-do-mundo-2010-faltam-x-dias, coppermine-integration, copy-link, copyright-licensing-tools, coremetrics, cos-html-cache, cosm, countdown-clock, counter, counterize, count-per-day, countryflag, cozimo, cpalead-wordpress-plugin, crawlrate-tracker, crazyegg-integrator-for-wordpress, create-coupons-coupontank, cricket-score, critical-site-intel-stats, crony, croppr, crossfit-benchmarks, cross-rss, crossslide-jquery-plugin-for-wordpress, crowd-funding, crunchbase-widget, cryptex, cryptx, cslider, css3-buttons, css-javascript-toolbox, css-js, css-js-booster, cs-tools, csupport-live-chat, csv-2-post, csvpig-mass-import-plugin, cube3d-gallery, cumulusjq, currency-conversion-guide, currency-converter, currently-ing, currex, curs-valutar-bnr, custom-admin-branding, custom-adsense-plugin, custom-coming-soon-page, custom-content-type-manager, custom-content-types, custom-css-and-js, custom-css-manager-plugin, custom-event-espresso-list-displayer, custom-field-images, custom-field-matrix, custom-fields, custom-fields-for-many-dates, custom-field-suite

Directly Printing Scripts/Styles: The Solution

Use the enqueues system built into WordPress for adding scripts and styles to pages.

A good reference for what hooks to use for script and style enqueues can be found at http://bit.ly/vYw3SY

Bad Menu Slugs for Dashboard Menus: The Example

add_menu_page('Name', 'Name', 8, __FILE__, 'callback');

add_submenu_page(__FILE__, 'Name', 'Name', 1, basename(__FILE__), 'callback');

Notice the use of __FILE__ in these examples.

Bad Menu Slugs for Dashboard Menus: The Problem

The argument that used __FILE__ in the previous examples is the $menu_slug argument. This is the name that is used for the page= argument to load the menu page.

I believe that this practice started from a very old set of example code that was copied and pasted an untold number of times.

Bad Menu Slugs for Dashboard Menus: The Problem

While this may not seem like a big issue, and the code that does this works just fine, it can easily create issues. If the menu slug ends up set to admin.php based on the name of the file with the function call, then other menus added by plugins will have their pages broken with a message that simply says:

You do not have sufficient permissions to access this page.

Bad Menu Slugs for Dashboard Menus: The Problem

The following are just a small sample of plugins that have this issue (in 5pt):

001-prime-strategy-translate-accelerator, 0mk-shortener, 1-bit-audio-player, 1-blog-cacher, 1-click-adsense, 1-click-retweetsharelike, 1-for-wordpress, 1-jquery-photo-gallery-slideshow-flash, 2checkout-donate, 2d-barcodes, 2focus-bookmarks, 2parale-for-wordpress, 3b-meteo, 3d-pix, 3d-twitter-wall, 3rd-party-authentication, 404sponsoring, 5gig-concerts, 7feeds-news-ticker, 7hide, 7uploads, a2billing, abagraph, ab-google-map-travel, about-me, a-broad-hint, ab-scriptsplit, absolute-privacy, abstract-submission, ab-video, access-keys, ace-certificazione-energetica, actionable, active-directory-authentication, active-directory-integration, active-plugins-on-multisite, actualiza-twitter-usando-niqmx, adapas-lastfm-plugin-for-wordpress, ad-buttons, ad-coder, adcrunch-quick-shortlinks-for-wordpress, add-all-nav-links-to-bp-adminbar, add-browser-search, add-category-and-rss-menu, add-flickr-photo-with-geo-tag, add-icons-to-sidebar-of-categories, add-icons-to-sidebar-of-categories-and-pages, add-image-to-post, addinto, add-logo-to-admin, addmarx, add-pheedo, add-post-footer, add-post-to-facebook, addremove-form-outlines, add-tags-to-posts, addthis, addthischina, add-to-bohemiaa-social, add-to-digg, add-to-facebook-plugin, add-to-orkut, add-users-to-posttype, add-widgets-to-page, add-your-comment-link, add-youtube, adfly-wordpress-plugin, adgallery-slider, adicons, adicon-server-16x16, ad-injection, ad-inserter, adknowledge-engage, ad-logger, ad-manager-wpbb, admangler, admin-author-notification, admin-bar-disabler, admin-bar-minimiser, admin-comment, admin-header-note, admin-log, admin-menu-tamplate-plugin, admin-pack-by-site-caseiro, admin-renamer, admin-renamer-extended, admin-sms-alert, admiyn-juitter-wordpress-plugin, ads-adder, ads-by-cb, ads-by-country, adscaptcha, adsense-attachment-plugin, adsense-daemon, adsense-deluxe2, adsense-deluxe-revived, adsense-extreme, adsense-for-wordpress, adsense-insert, adsense-now-lite, adsense-on-top, adsenseoptimizer, adsense-plugin, adsense-stats, adsense-wow, adserve, ads-for-old-posts, ads-manager, advance-audio-player, advanced-iframe, advanced-media-button-remover, advanced-responsive-video-embedder, advanced-tagline, advanced-tinymce-configuration, advanced-youtube, advance-pagebar, advance-post-url, advertise-in-text, advert-manager-plugin, advertwhirl, ad-wizz, adwork-media-ez-content-locker, ad-wrap, affiliate-easel-for-amazon, affiliate-link-cloaking, affiliate-overview, ag-custom-admin, age-calculator, agenteasy-properties, agent-storm, aidaxo-yfgallery, air-badge, aixorder, aixostats, ajaxchat, ajax-comment-pager, ajaxd-wordpress, ajax-feed-reader, ajax-quick-subscribe, ajax-random-posts, ajax-save-post, alakhnors-post-thumb, a-lead-capture-contact-form-and-tab-button-by-awebvoicecom, alert-before-your-post, alexarank, alianzablogs, aliiike-web-recommender-system, all-author-page, all-category-seo-updater, all-in-one-adsense-and-ypn, all-in-one-adsense-and-ypn-pro, all-in-one-facebook-pack, all-in-one-gallery, all-in-one-seo-pack, all-in-one-social-network-buttons, all-in-one-webmaster, allone-autoresponder, allopress, allwebmenus-wordpress-menu-plugin, alter-feed-links, altstats, amazing-youtube-player, amazon-affiliate-system, amazon-associates-wordpress-wishlist-plugin, amazon-einzeltitellinks, amazonfeed, amazonify, amazonpress, amazon-press, amazon-s3-photo-gallery, amazon-s3-simple-upload-form, amazon-s3-url-generator, amazon-search, amazon-widget, amcaptcha, amr-clearskys-availability-modification-for-27, amy-lite, analog-clock-10, anflex-ga, aniga-gallery, annie, announcement-and-vertical-scroll-news, announcement-ticker-highlighter-scroller, announcer, anobii-wordpress-widget, anonimacao-ctdo, another-author-box, anti-manpower-spam, anyvar, apercite, aphorismus, app-display-page, append-content, appointy-appointment-scheduler, appsgeyser-plug-in, appstore, aprils-call-posts, aprils-facebook-like-button, apture, archive-manage-widget, are-you-a-human, arkavis-games-sidebar, arkayne-site-to-site-related-content, arrowchat-wordpress-integration, arslania-acronym-kelimeler, article2pdf, article-directory, article-directory-script, article-forecast, articles-protection-plugin, artists-ilike, asideshop, askapache-crazy-cache, askapache-firefox-adsense, assign-missing-categories, at-internet-analyzer-ii, at-internet-analyzer-nx, atropos, attach-files, attachments, att-youtube, austin-tech-events-calendar, authldap, author-bio, author-bio-box, author-comment-replies, author-geolocation, author-hreview, author-name-in-rss-feed, author-notify, authors2categories, author-signature, auto-approve-comments-for-specific-posts, auto-blogroll, autocap, autochimp, autoclose-comments, autocompleter, autofields, auto-ftp, auto-image-field, auto-link, auto-link-best-tags, autolinks, automatic-facebook-converter, automatic-glossary, automatic-links, automatic-seo-links, auto-media-insertion, autonav, auto-post-posts, auto-post-title, autopublish, autoresponder1, autoresponder-gwa, auto-tag, autotopo, auto-trackback-by-category, auto-trackback-by-category-for-wordpress-23, auto-translator, auto-tweet, auto-twitter-followers-stay-informed, ava-basic-video-gallery, avantlink-related-products, avatars-for-comment-feeds, ava-video-gallery, aweber-registration-integration, aweber-test-drive-widget, aweber-web-form-widget, awsom-drop-down-archive, awsom-news-announcement, awsom-pixgallery, awstats-xtended-info, babelz, background-changer, backlink-cloud, backtop, backup-content-as-txt, bad-behavior-log-reader, bad-behaviour-log-reader, bad-comments, badge-grab, baidu-share, baidu-sitemap-generator, baltic-amber-admin-themes-and-schemes, banner-cycler, banner-design, banner-generator, bannerspace, banner-wizz, batch-cat, batch-validator, baufinanzierung, baw-autoshortener, baw-like-unlike, baw-wordpress-plugin-security-checker, baza-agentov, bbaggregate, bbcode-shortcut, bbcode-w-editor, bbinfo, bbpress-quotes, bbredirector, bbsigpress, bbuinfo-blogblogs-user-info-plugin, bbus-ezinearticles-search-api-widget, beacon-wordpress-plugin, beautiful-social-web-link, bei-fen, best-post-page, best-posts-summary, bestsmallshoplite, best-social-share, best-wordpress-seo-plugin, betteramazonapi-amazon-plugin, better-notes, better-utf8-excerpt, better-wiki-links, bft-autoresponder, bhu-c2s, bibleverse, bible-verse-display, biblia-online-vivendo-a-palavra, bibly, bibs-minimanager-reloaded-german, bibsonomy, big-cartel-plugin, bilingual-linker, binimg, binlayerpress, bitacorascom, bittads-for-wordpress, bizsugar-vote-button, bizsugar-voting-button, blackwater-album-manager, blakelt-wordpress-integration, bl-countdown-timer, blindall-slideshow, blindx-slideshow, blindy-slideshow, blindz-slideshow, blippr, blip-tv-episodes-widget, blog2print, blogarate-rating-widget, blog-as-pdf, blogcopyright, blogger-image-import, blogger-portfolio, blogger-title-fix, blogger-to-wordpress, bloghint, blog-introduction, bloglines-reader, bloglovin-follow, blogmappr, blog-mechanics-keyword-link-plugin-v01, blog-mechanics-theme-gallery, blog-metrics, blogorola-wordpress-plugin, blog-promotion, blog-protector, blog-protector-final, blog-quickly-shout, blog-reordering, blogroll-links, blogroll-links-page, blogsense-connect, blogshotr, blogtal-trackback, blog-templates, bluagent-block-user-agent, bluedaumview, blueding, bluetrait-connector, bluetrait-event-viewer, bmlt-tabbed-ui, bm-tweet-this, bobs-simplistic-navigation, bohemiaa-social-fan-box, bohemiaa-social-share-and-fan-box, boobtube, bookcottages-availability-calendar, book-cover, booking-framework, booking-manager, booking-search-hotel, bookitme-booking-calendar, booklinker, bookmarker, bookmark-export, bookmarkify, bookmarking-made-easy, bookmark-now, bookstore-search, booktuner, bookx, boslideshow, botproof-captcha-20, bot-tracker, bot-trap-logfile-reader, bouncecc-blog-monetizer, boxer, brafton-feeds, brainshark, brand-regard-plugin, brinkin-banner-exchange, broken-links-remover, broken-rss-feed-fixer, browser-blocker, browser-sniff, browser-specific-css, browser-themer, bsuite, bubs-button-board, buddypress-easy-albums-photos-video-and-music, buienradar, bulk-delete, bulk-description-update, bulk-move, bump-the-schedule, bundesliga-table, bunnys-print-css, buoy-conditions, buscape-tracker, business-directory, buzz-comments, buzz-feed, buzzthis, buzz-this, buzzz-et, buzzzy-button, bw-less-css, bw-twitter-blocks, bw-widgets-manager, bye-maridjan-seo, bye-papa-destra, byob-thesis-simple-header-widgets, byrev-gallery-pagination-for-wordpress, c7-title-scroller, calais-auto-tagger, calculatorpro-calculators, calendar-archives, calgraph, call-to-action-plugin, call-tracking-metrics, cameroid-photos-online, captchaad, capture-the-conversation, carousel-free-video-gallery, carousel-video-gallery, cartpauj-pm, cas-authentication, cashie-commerce, castmyblog, category-import, category-listings, category-mapping-plugin-for-wordpress-mu, category-page-icons, category-search, category-specific-rss-feed-menu, category-templates, category-text, category-visibility-ipeat, catfeed, catfish-ad-manager, cathopedia, cattagart, cawaii-admin, cdokay-tv-youtube-video-gallery, censortive, cf7-calendar, cgm-event-calendar, chacha-answers, chango-wordpress-plugin, chaxpert, cheatsheet, checkfront-wp-booking, check-links-intercambios, chesser-autoreplace, chesser-copyright, chess-game-viewer-control-panel, chibipaint-for-wordpress, chimpblast, chinese-new-year, chitika-linx, chopy-shop, cincopa-video-slideshow-photo-gallery-podcast-plugin, citation-aggregator, citation-manager, cite-this-post, cj-change-howdy, cj-custom-content, cj-datafeed, cjk-autotagger, claptastic-clap-button, classifieds-plugin, cleancode-exclude-pages, cleancode-favorite-posts, cleancodenz-geo-posts-plugin, clean-titles, clean-wp-dashboard, cleveritics-for-wordpress, clickatell-sms-subscription-manager, clickbank-hop-ad, clicktale-analytics, click-to-call, clikstats, clima, climate-change-glossary, clipta-video-informer, cli-switch, clix-post-category-excluder-for-wordpress, clone-spc, clouds, clply, cmailer, cm-newsletter, cms-press, cm-subscriber-stats, cms-vote-up-social-cms-news-button, cobwebo-url, collapse-page-and-category-plugin, color-admin-posts, colorcode, color-keywords, comenta-wp, comment-author-url-stripper, commentify, comment-inform, comment-log, comment-recovery, comments-to-nabaztag, commentsvote, comment-toolbar, commenttweets, comment-url-control, comment-warning, community-ads, communitypress, community-submitted-news, compactrss, comparepress, compartir-en-tuenti, complexlife, confirm-user-registration, connect-pictage-to-wordpress, constant-contact, constant-contact-form, contact-commenters, contact-export, contact-form-8, contact-form-captcha, contact-form-plugin, contactme, contact-me-widget, contemplate, contenshik, content-and-excerpt-word-limit, content-management-system-dashboard, content-pay-by-zong, content-progress, contentresize, content-slide, content-text-slider-on-post, content-warning, content-warning-v2, contextual-ppc-revenue-by-advtisecom, continuous-announcement-scroller, continuous-rss-scrolling, conversation-starter, cool-author-box, cool-contact-form, cooleye, cool-fade-popup, cool-tags, copyfeed, corner-blog-decoration, cos-html-cache, countdown-timer, countdown-to-next-post, countryflag, coupon-script-couponpress, courier, coursemanagement-cm, cpaleadcom-wordpress-plugin, cpalead-wordpress-plugin, cpanel-operations, cp-redirect, create-facebook-fan-page-custom-tabs, create-qr-code-wordpress-plugin, creative-commons-license-manager, cron-demo, crossfit-benchmarks, crossposterous, crosspress, cross-registration-integration, cr-post2pingfm, cslider, css-naked-day, csv-2-post, csv-importer, csvpig-mass-import-plugin, csv-to-webpage-plugin, cube3d-gallery, curateus, current-location, currently-ing, currently-listening-to, currentstatus, custom-about-author, custom-author-permalink, custom-comment-fields, custom-copyright, custom-css-manager-plugin, custom-login-logo-lite, custom-more-link-complete

Bad Menu Slugs for Dashboard Menus: The Solution

The menu slugs should be short descriptive strings that are unique to 1) the project and 2) the menu page. There is no reason to tie these names to the name of the file running the code.

The following are examples of good menu slugs for a plugin called Example Plugin Project:

caj-epp-configure-settings

caj-epp-manage-entries

[author initials]-[project initials]-[verb]-[noun]

Not Prefixing Functions, Classes, and Vars: The Example

Going straight to a code example, consider the following:

function load_settings() { global $settings; $settings = get_option( 'my-settings' );}

Notice how every name used, the function name, the global variable name, and the option name are each very generic and could easily apply to any project.

Not Prefixing Functions, Classes, and Vars: The Problem

The issue with using generic names for functions, classes, global variables, and names such as names for options, menu slugs, action/filter hooks, and scripts to be enqueued is that they can quickly collide with names used by another developer if they also use generic names.

If two plugins use the same function or class name, PHP crashes and most people will see a blank white screen with no idea of how to fix it. If two plugins use the same variable, then very unusual problems can occur with seemingly-random results.

Not Prefixing Functions, Classes, and Vars: The Solution

The solution is simple, always, always, always prefix anything your plugin exposes to the rest of the WordPress ecosystem.

Not Prefixing Functions, Classes, and Vars: The Solution

For functions, actions, filters, and other items that do things, I use the following pattern:

[author initials]-[project initials]-[verb]-[noun]

Such as:

caj-rfp-load-optionscaj-dsn-filter-rotary-girderscaj-aep-enqueue-scripts

Not Prefixing Functions, Classes, and Vars: The Solution

For variables, option names, classes, and other items that represent something, I use the following pattern:

[author initials]-[project initials]-[noun]

Such as:

caj-tirn-settingsCAJ_SEF_Author_Widgetcaj-uwriq-features

Enqueueing Scripts Everywhere: The Example

function caj_epp_add_menu() { add_theme_page( 'Name', 'Name', 'manage_options', 'caj-epp-edit-settings', 'caj_epp_show_settings_page' );}add_action( 'admin_menu', 'caj_epp_add_menu' );

function caj_epp_add_scripts() { wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'media-upload' );}add_action( 'admin_print_scripts', 'caj_epp_add_scripts' );

Enqueueing Scripts Everywhere: The Problem

The code example above enqueues the jquery and media-upload scripts on every admin page. While this may seem harmless, it can easily cause problems.

If you enqueue your own custom scripts on every admin page, you can now cause conflicts with other plugin's scripts on those plugin's pages... on pages that don't even involve your plugin.

Enqueueing Scripts Everywhere: The Problem

This issue isn't just limited to custom scripts.

If you enqueue styles in places where they aren't supposed to be enqueued, you can break the styling of the output of other plugins, other themes, or WordPress itself.

In addition, some WordPress-provided scripts can cause problems for other projects. A good example is the media-upload script, which changes how all Thickboxes behave.

Enqueueing Scripts Everywhere: The Solution

Since most scripts and styles that projects add to the Dashboard are meant to only be added to the pages specific to that project, you can simply use a page-specific action to ensure that the scripts and styles are only added to those pages.

The key is to save the hook suffix returned by the function used to add the Dashboard menu entry. This is then used as part of the admin_print_styles-$hook_suffix or admin_print_scripts-$hook_suffix action hooks.

Enqueueing Scripts Everywhere: The Solution

function caj_epp_add_menu() { $hook_suffix = add_theme_page( 'Name', 'Name', 'manage_options', 'caj-epp-edit-settings', 'caj_epp_show_settings_page' ); add_action( admin_print_scripts-$hook_suffix, 'caj_epp_add_scripts' );}add_action( 'admin_menu', 'caj_epp_add_menu' );

function caj_epp_add_scripts() { wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'media-upload' );}

Not Using WP_DEBUG: The Example

Hello

Not Using WP_DEBUG: The Problem

Unless you run with WP_DEBUG enabled on your site, you will never see a problem, but for other developers that happen to run your code and do use WP_DEBUG, they will see the following until the name index of the array is set:

Notice: Undefined index: setting in /home/user/public_html/wp-content/plugins/example-project-plugin/public.php on line 5

And this is with just one instance of this issue. Imagine if your code had dozens of issues like this.

Not Using WP_DEBUG: The Solution

Add the following to the wp-config.php file of every site you develop on:

define( 'WP_DEBUG', true );

Make sure that you watch for your code to produce warnings, and fix them when you find them. If you have an existing project, erase all of its saved data (delete the option, clear the tables, etc) and check again to confirm that no warnings are produced.

Not Using WP_DEBUG: The Solution

Create a function to have set defaults that returns the data.

function caj_epp_get_settings() { $defaults = array( 'name' => 'User', ); return get_option( 'caj-epp-settings', $defaults );}

Use this function to get the settings.

Hello

Using Example Code Without Modifying It: The Example

Rather than directly picking on anyone, I will simply suggest that the examples used throughout this presentation typify the type of solutions you can find in books, on blogs, in help documents, on support forums, and just about anywhere else.

In fact, most of these worst practices come from people simply copying and pasting code that they found elsewhere, leading to duplicate functions, spreading bad practices, and other conflict-causing problems.

Using Example Code Without Modifying It: The Problem

When you take someone else's code, you also take all of its problems. In addition, you easily run the risk of having duplicate function, action, etc names.

Just think about it. If you found that tutorial helpful, someone else is likely to have thought the same thing and is just as likely to have copied and pasted the same example code.

Using Example Code Without Modifying It: The Solution

When you take code from examples, avoid the problems talked about in the rest of the presentation.

Make sure that you prefix functions, global variables, etc.

Check that the code doesn't dump any warnings by using WP_DEBUG.

Make sure that it doesn't change core scripts/styles or add them directly to the page.

Using Example Code Without Modifying It: The Solution

In short, if you take someone else's code, make sure that you actually test it and make it your own. After all, now that you've rolled it into your code, it is now yours and you are responsible for it.

Concluding Thoughts

As a developer, you need to remember that your code doesn't just affect you. Your code affects every user that puts your code on their site, every visitor to those sites, every plugin or theme that runs on those sites, every developer behind each of those themes and plugins, and even WordPress itself.

It sounds like a huge burden, but in reality it is your responsibility as a developer. Your goal should not be just making something work; you should also want it to work well.

Concluding Thoughts

My hope is that I shifted some of your thoughts on development, to make you think of how you have a responsibility to those that use your code and to other developers.

Chris JeaniThemes.com Developer