################################################# The following notes are copyright Steve Grimm and used with permission. Steve Grimm | Web Developer Unstandardized Design design.unstandardized.com ################################################## DRUPALCON NOTES! Themer's Toolkit - Wednesday, 3/4 ========================================= Starter Themes - the zen theme... never used it, but she recommends it. - Drupal 6 uses an info file for themes, just like modules. ** Converting from Drupal 5 to 6 ** - Create an info file - define regions in info -ex: regions(above_header) = above header - stylesheets in info ** Top tools ** - Firebug - Browsershots.com - screenshots from lots of different browsers - devel - themer info (I think this is for drupal 6 only) - shows you the template files that you are in, and which ones you can use. - I think I've tried this out... will be useful for drupal 6. - zotero.com - useful for quickly changing design - kinda missed why its good... check it out. - design "library" . . . - css grids - blueprint, yahoo, 960gs, gridworks - revision control!!!!! - http://bazaar-vcs.org/BazaarUploadForWebDev - distributed version control system... - you don't need to be connected to the internet to use it. - work locally, push it back to central machine. - zero overhead (is this free?) - good for working alone. this could be my version control system! - windows, linux, osx. - NOT SCARY! - frontenddrupal.com (her book) - IDE recommendations - she uses VIM (probably not going there) - netbeans - there is a drupal-specific plugin (windows, osx, linux) - flip color scheme! will save your eyes! - she starts from zen - step-through debugging with komodo . . . ? ===================================================================== ===================================================================== =================== STATE OF DRUPAL KEYNOTE ========================= ===================================================================== ===================================================================== ================== Rocking your Dev Environment ===================== - all of her notes are on a blog, gotta get the URL! - she says "know your tools inside and out" and "know drupal inside and out".... - will I do that, probably not. - windows sucks for development - dualboot... or maybe virtual machine? - her tips 1. Firebug - people love it... I just use web developer toolbar 2. Firefox -ProfileManager -no-remote : use two different sessions of firefox, from the same browser. So, you can be a user and an admin at once. Creating profiles in firefox. 3. Tamper Data - firefox plugin I believe 4. Macros - iMacros - lets you play back a series of actions, so I don't have to buy something over and over when testing a store, for instance. 5. Drupal for Firebug - extension (firebug) plus the drupal module - user objects, node objects, forms, you can run php code. NICE! Used with the devel module. Tracks queries and records them in a window. Shows messages...huh? Look into this for sure! 6. Admin menu - yeah. 7. Devel - SMTP libary - log mail, instead of sending it! 8. Simpletest - unit testing framework for php and drupal...? how? 9. Login Toboggan - pops in a login page on any access denied page... but it broke something on PBT, so I haven't used it. 10. Xdebug - extension for PHP, prettifies var dumps...? can be done straight forward in eclipse - lets you step through your code, can look at variables without dumping them. What PHP debugger do I like? I don't know! 11. Use source code configuration management. So, VCS. Source Code Control (git, cvs, subversion) 12. Check in your entire source tree...? not just your sites directory, do it all. 13. Organize your source code...? What? Sites/blah.localhost (so, not just sites/all!) Use this to separate your code from 3rd party stuff. That's a great f-ing idea. 14. Check in clean source for 3rd party modules... what? Change it before you tweak it. 15. Test all upgrades against a production copy. Learn how to write update functions, sets variables, create nodes, huh? Put a copy of your site on a local development system (grab the database), and run the update script (upgrade script) on it. So, basically instead of changing something directly, use upgrade functions. 16. Manage your branches and merge changes. What? Working on development branch, and you commit changes to your production branch. There are tools for merging the two branches. So... create a branch for production and one for development. Merge the two. 17. Use build tools. Makefiles! make sql, make backup, make restore, make clearcache, make test - run project tests. So, first figure out the commands (make sql connects to db), then use makefiles to do certain things (especially backup and restore). She uses doxygen for documentation. ?? 18. Example target: backup: mysqldump -u ${DB_USESR}\ --password=${DB_PASSWORD} ${DB} --opt --complete-insert --max_allowed_packet=1M $ {SQLOPTS} > sql.dump basically a command for dumping the database, but use build tools... to do this? 19. Make tools to save you work - get better in linux! scripting.... Invest time in bash scripting (or even php for this kind of scripting). This is why you use linux. 20. Drush - I've heard of it, wtf is it really? Drupal shell - drush eval node_load(200); - lets you load a node, or just run some functions and see what happens! Check out the drush readme if I decide to actually learn this. Great for unit testing (whatever that is!). 21. Simpletest (ok, now onto unit testing), I should consider learning it because its very useful (she says). "Tip: Define your own base test case class." - for instance, delete all the users matching a certain query, or all of the nodes matching a certain query. ------------------- Tips from the audience! - so far, this shit is over my head - Unfuddled - version control is used with this and tickets...? check it out online. Bug tracking system... good FREAKING idea! - Trace module (drupal.org/project/trace) - tracing of hooks, microsecond timing... look it up!!! - groups.drupal.org - drubuntu - how to setup multisite with apache that can make staging sites easier. One for 5.x and one for 6.x. - Coder drupal module - fixes drupal module code? Spaces instead of tabs. - another vote for netbeans. drupal plugin for it. check that shit out! - she might release her makefiles! check out her blog...? where?! - keep these things OUT of your production server. - use install profiles they say. how? learn it. - check out aeger? http://bit.ly/drupal25 ======================================================================================================= ============================ Handling Asynchronous Data with Drupal =================================== Josh Koenig - chapterthree.com, g.d.o/drupal-dojo, old timer AHAH/AJAX/ETC - its the hotness. Browser becomes a platform. Yeah! The Drupal Flow -------------------------- Browser -> Drupal -> Browser jQuery and Drupal.behavior -> Drupal (xHTTP) -> Async Responses Mission: async_demo.module - provide a block of links to non-promoted posts - links cause post to appear on top of /node - Use Drupal behavrios to hook into jquery - Menu callback to provide the content Booting Up: Iniitial State Tips for Winners - Build Object Level Data into the DOM - Use Drupal.Settings for Global Info (basepack variable) - Keep your HTML Compliant (don't make up your own attributes - not futureproof) - Degrade as Gracefully as Possible - Code example - Drupal.behaviors - Hook to DOM elements with jquery - Better than $(document).ready() - override friendly - re-attachable - contextual Why Behaviors? - for instance - node edit form in a thickbox - fieldsets won't collapse! the javascript doesn't work... - you can rerun your behaviors and rehook within a context... ok... how? Drupal.behaviors.asyncTeaser = function(context) { $('a.async-teaser-show', context).bind('click', function() { var params = $(this).attr('id').split('-'); asyncFrontPageTease(params[1]); return false; }); } // actually grab the teaser, and fade it in (we pass the nid to get) function asyncFrontPageTease(nid) { var callback = Drupal.settings.basePath + 'async_teaser/' + nid; $.get(callback, function(data) { $('#squeeze .clear-block:first').prepend(data); // where we are going to put our data $('#node-'+nid).hide().fadeIn(500); // bring it in! }); } AJAX Menu Callbacks - implement hook_menu() as usual - Finish with print() instead of return() -> because its javascript asking, we print and it sends it back to js - For structured data, use drupal_json() (or maybe theme_ahah?) // returns php array as json! - Be aware of other outputs (e.g. devel) - don't let other output bust your shit up. - try exit() after printing to avoid devel output Taking it to Scale! - State / Status - 10,000s requests - live means up-to-the-second - each xhtml request is potentially a full drupal bootstrap - thats expensive! - design your flow accordingly Techniques - earlier drupal bootstraps - Bootstrap is Good - DRUPAL_DATABASE allows you to read from DB w/less Drupal - Utilize your variables, db connections, etc - No access control or other functions - about 10x faster than a full bootstrap - STILL NOT FAST ENOUGH! - dedicated live.php handler - static filestore - Static files are BETTER! - write to a file, js reads file - apache is Cheap (serving static file) - easy to write JSON to some place in /files - easy to tell jquery where to look w/Drupal.Settings() - easy for jquery to grab/parse/act - POSSIBLE ISSUES - clustered application servers (files might not be in sync); lots of read/writes; garbage collection - memcached - memcached = en fuego! - you need to learn it if you want to run high end systems - shared cloud between many servers - legendary speed - dedicated PHP handler = low overhead - integrate with other caching strategies - roll with the thunder! Drupal Example: Live updated = http://drupal.org/project/live_update - flexible set of methods for responses - API for status changes and content updates - Implemented for PBS engage live chat Keeping it Safe - Know what needs securing - always use full drupal for writes - session ids and tokens can help - database table with tokens, check it to see if its a real vote AJAX FORM SUBMISSIONS The Holy Grail - needs to work off form api - use standard #attributes - submits to same URL that drupal normally submits to Currently Available Contribs - ajax_submit.module (oldschool, a developers module) - ajax.module (newer, ajax_submit is going this way) - ahah_family (eg. ahah_response) - form submits, dynamically browse a site AJAX Submit - attach via #ajaxsubmit FORM API attribute - custimizable JS callback functionality - Handles errors and previews * SEE SESSION PAGE FOR PRESENTATION (or chapterthree.com blog) ============================================================================================ ============================= Advanced Theming Techniques ================================== ============================================================================================ is.gd/IG0u - link to the slideshow (could be an L instead of an I) - maybe can look at them later... - Anatomy of a theme - .info file (drupal 6, I guess everything is drupal 6 now) - template override - function override (functions in template.php) - theme at module level - .info files - add stylesheets, regions, provide default "settings" ?, include javascripts - template overrides - useful for people more comfortable with markup than code... - provides flexibility for subtheming - theme guide for drupal 6! - function overrides - 5x faster! (when compared to template files) - theming at module level - needed for theming new functionality... ok. Overriding - what Drupal theming is all about - How? - Template files - find the original template in - the base (parent) theme - PREPROCESS functions are better than template files! - separate logic from appearance - less code, less bugs, less maintenance - better handling of errors - HOW? template.php // we just wrap our block in a span - these preprocessors ROCK! function [theme_name]_preprocess_block(&$vars, $hook) { $vars['block']->subject = "".$vars['block']->subject.""; } - Theme Functions - Find the original theme function (contrib or drupal api) - paste it into template.php - change theme_hook() to NAME_hook() (name of theme) - results in duplicate code... so preprocessors are better in general. - Preprocessing theme functions - there is no preprocess for theme hooks, but you can modify the function arguments, then call the original theme function. e.g.: // override theme_links() function [name]_links($links, $attributes = array()) { // do stuff to change links, then return theme_links return theme_links(variables); } in template.php so, we do something like add a class ($links[$key]['#attributes'] = array('class' => 'next'); then we just run it through our normal theme_links function. clever! - check the theme registry to find out which is the current function that handles an object? - there is a global variable that holds the theme registry Subtheming - it just makes theming easier! its good in drupal 6. do it. Why? - exaggerate the defaults - get closer to final goal before writing any code - inherit, inherit, inherit, then override In drupal 6, subthemes go in sites/default/themes/ and NOT sites/default/themes/zen/ - Use zen for subtheming. - .info file tells you the parent - if using zen, copy starter kit into your theme directory - you can use any theme as your parent - Theme Registry - clear the cache... because the theme registry is cached. - Theming forms - there are special - gets passed through theme_form, which is why they all look the same. - need to grab the theme at the level of the theme registry, and tell it to use this template or this function. - HOW? - modify individual form elements - work around the entire form - node/22130909 - visit the link when you get to this point of the slide ex. in template.php function themename_theme($existing, $type, $theme, $path) { return array( // tell drupal what template to use for the user register form 'user_register' => array( 'arguments' => array('form'=>NULL), 'template' => 'user-register', this is the name of the template ), // whatever else ); } // now looks in your theme folder for user-register.tpl.php - sweet! so in user-register.tpl.php ============================================================ ============== Drupal Mailing Strategies =================== ============================================================ Users provide us with info - what do they send, what do they subscribe to, what do they comment on, how do they respond? - module -> Send (not strictly a send to friend module, although one is included. - API for tracking messaging through site - provides views support to analyze tracking data - MLM (mailing list manager) & News - maintain lists of subscribers - of any type - Store the lists in any backend - Deliver messages through Send's API - http://drupal.org/project/News - Users are in control - single interface for subscriptions - delivery preference - message format - everything is routed through the same API - Everything is tracked - who sent the message - how it was sent (send to a friend, forwarded, sent through new module) - who received it - which nodes were included - Why is this interesting? - now you know what content works - So, what's next? - let users control the flow of information - let them participate! - Watch Module - subscribe to any view - including arguments and filters - receive updates via RSS or the Send API - Subscribe to free-form discussions - Subscribe to discussion via watch - MLM recognizes discussion - Recipient can respond via email - Mimemail posts response to topic - basically, you can subscribe to a mini-version of a site's content, like dealnews.com! - Where we're at: - stable releases of Mime Mail and Send for Drupal 6 - MLM and News on the way shortly... - Watch at development snapshot Check out - http://drupal.org/project/simplenews also maybe easy mlm . . . . ? ================================================================ ====================== jQuery UI =============================== - make something draggable - give something an element class draggable, include jquery UI, and include draggable plugin. $('.draggable').draggable(); - easy - droppable - a drop area for the draggable object. - so you define an area (div) as droppable - gonna ask about hiding the shit on load for jcarousel! ========================================================================== ========================= SEO Tips and Tricks ============================ ========================================================================== SEO: - not fast - not a trick - a commitment - time consuming - all about effective communication You need a good online strategy to make money online. Bottom line. SEO TACTICS - Research - Good site architecture - TEXT navigation - KEYWORDS in navigation! - semantic markup, using code that has meaning to browsers as well as google. Never more than one h1 on page. (title of site) - using keywords in heading tags - using ordered and unordered lists - using meaningful anchor text (aka links) - Semantic markup - Content strategy - google likes content! - for a shopper, show them things they can buy. if they want to do research, give them info. duh! - Inbound links - a link is the currency on the internet. site that gets the most votes, shows up the highest - so you have to get good inbound links! - strategies: - press releases - contact other businesses and asking them - blogging on other websites - directories - 90% of the time on SEO is building a good inbound linking campaign. - the hardest thing to do, basically you have to have legit content that makes someone want to link to you. - "walled garden" attitude - you don't want to send people away - this is stupid! visitors are not idiots. - dmoz open directory project (and yahoo directory) - REGISTER EVERY SITE (do it for 10 years) - dmoz.org - the length of registration matters! register the shit out of your domain!!! - if your domain is going to expire soon, to google you MIGHT be a spammer - Taxonomy - TAXONOMY TAGS are very important, put them in an H1! - SEO Modules for drupal - SEO Checklist - pathauto - page title - global redirect - path redirect - meta tags - XML sitemap - google analytics - benchmark and measure - are meta tags... useful? - keywords, description, title -> the most important one is title (#1!!!) - keywords don't do shit, description is what google will show on search listing - description increases click-through rate, but not search ranking - geolocation meta tag - RESEARCH IT because its a good fucking idea! Lets google know WHERE YOU OPERATE! - redirects - different types of redirect, the best way is with http status code for the page - what code? depends on goal. 301 = permanent redirect, transfers google juice. - global redirect module - reduce duplicate URLs on your site. node/1 and about-us -> two different URLs = duplicate content penalty. So, the global redirect module sees an incoming request, and sends people to better requests with a 301 redirect. NICE! - path redirect module - create redirects manually... for migrating old site to drupal (LOOK AT THIS FOR solb!!!) - look in watchdog to see what the bad URLs are. Or look at google webmaster tools. - new tag - CANONICAL TAG! if you have duplicate content, you can put a tag on your page - we don't need it, because global redirect module does the work for us. - www.me.com and me.com is TWO DOMAINS, so just pick one and enforce it!!! - USE GOOGLE WEBMASTER TOOLS - Drupal works pretty well out of the box - leave page titles! make sure they change based on the title of the page. - leave node titles alone. - Selling SEO - name recognition, organic search traffic, sales, donations - investing in SEO pays dividends, if you do it right - What do you sell? - research - keyword analysis - content strategy - training - measurement and evaluation - seomozpro will analyze a site versus its competitors - http://www.seomoz.org/ - benchmark a clients site BEFORE YOU DO THE WORK, so you can see! - look in my green bag for a case study on measuring a baseline. - groups.drupal.org/search-engine-optimization - volacci.com/drupal - growvs.com - seomoz.com - google's SEO handbook & webmaster tools - ideally the most important keyword is the first word in your title tag - will adsense help or hurt ranking? no evidence - submit the site to delicious and dmoz and reddit and all that good stuff! - page title module allows you to set the page title manually or programmatically - nofollow for overhead pages? - overhead = user login, contact page, privacy policy, etc. - its called pagerank sculpting - use nofollow for those pages - STOP SUBMITTING SITEMAP ALL THE FUCKING TIME! - done ********************************************************************************************** ********************************************************************************************** **************************************** DAY TWO ********************************************* ********************************************************************************************** ============ Scaling, not IF but HOW =============== - stuff about queries and the devel module, know it. Implement Caching - Types of caching - standard drupal cache - easy to implement = good - relies on the database = bad - APC - standard drupal cache + memory - much faster performance than anything = GOOD - not networkable, so only on one server = BAD - Memcache - standard drupal cache + memory + multiple servers (good) - network based protocol, all it really needs is a server with good RAM - limited control over when and how things disappear from cache (bad) - static file caching / Boost - insanely fast (good) - only good with anon users (bad) - Page cache - cache's full pages, but only works for anon users (static content) - block cache - configurable to work with anon users, as well as logged in users -can be page specific, user specific, borth, or site wide - it can be hard to control when the data expires - Implementation - static variable cache -> create a static variable, it will be valid for the entire length of a request. - programmatic data cache -> use cache tables - done did it on PBT! He recommends what I did! - Monitoring!!! - cacti - free! monitor various aspects of your site, trend visualization (ask Dan!) - mysql enterprise manager - gomez OTHER OPTIONS - front-end techniques - .5s to generate and 7s to render, its slow! - use YSlow!!!! Get a score on how fast front end is. plugin for firefox... awesome! - JS aggregation/compression - load js at the bottom! - YSlow! - JS Aggregation -> 33% faster!!!! Fucking a! Drupal 6 has built-in js aggregation. - DO THIS FOR PBT!! - There is a module for 5.x!!! - JS minification -> unsafe in PHP, but you can do it manually - apache tweaks - gzip compression - move .htaccess to your http.config (if you can!) - basically, you turn OFF htaccess! - CDN - load stuff from afar, relatively cheap, easy to implement - check out SimpleCDN! Like workhabit. cachefly.com. - SimpleCDN mirrors your content, check it OUT! - http://www.simplecdn.com/ - works to speed up your end-user experience QUITE A BIT. - Far future expiration headers...? - How to simulate heavy traffic? - generate a test script, (using firefox and jmeter?) - static file + javascript in the non-static content. = good idea! ===================================================================== ==== Building Infrastructure You Can Scale, Monitor and Maintain ==== ===================================================================== Step 1 - design your architecture... way before the launch, did this for PBT (kinda) - predicting traffic, look at the top hour in a given month to plan for your peak traffic. - factor in planned growth. - CDN used for static content - might be a great idea for sites like solb for speed, especially if simplecdn is cheap! Segment out your traffic: - load static content straight out of a cdn - gets it off your server and out of your mind - load balancer for dynamic content, going to reverse proxy cache servers - reverse proxy cache servers - you configure rules on them, and before you get to drupal, you ask that servre if it has the content ready (1000s of request per second) - next we have your actual application server (your drupal server) - it goes into your database, this is the most expensive place - so basically, the goal is to try and filter as much traffic as possible away from your application and database. Offload from the master database - slave database (oh lord), memory cache, offload search - basically, you never want to run search in mysql. - Your master database is the single greatest limitation on scalability. - Apache Solr for search (acquia is hosting it now) - Squid or Varnish are good for reverse proxy caching (Varnish is better) - any third party CDN will work Management - usually he uses a separate machine specifically for managing/monitoring. Usually it offers a web interface for making configuration changes and seeing how things are going. Managing the Cluster - you want a server that talks to every server - Shared storage (NFS) - not necessarily a good idea, single point of contention and failure. - Capistrano - his tool of choice, provides near-atomic deployment, service restarts, automated rollback, test automation, and versioncontrol integration (tagged releases). ============================================================================== ============= Rich text, Poor text, managing content in drupal =============== ============================================================================== - Asset module does basically what you think, you upload images and they become assets. - supposedly better than IMCE, because IMCE doesn't use imagecache - Desktop blog publishing clients (might be good for people to post content!) - Mac: ecto, MarsEdit, Qumana, TextMate - PC: Raven, Windows Live Writer, Qumana - Linux: Thingamablog - still have the input filter problem... - can be good for filling in the body of a post, and then you go in and add pictures in the website... - What You Say is What You Mean - plain text can be formatted without HTML. - WYSIWYM filters allow text o be readable as plain or rich. - Easier to install/configure. - these are just input filters... - ex: Header Name ------------ Once, there was a placeholder paragraph amed Tina. She was **very** excited about her new list: 1. Item 1 2. Item 2 ----------------------------------------- | Text | More Text | something else | | blah blah | blah blah blah blah | blah | ----------------------------------------- how to make a table!!!! =============================================================================== ================== Optimizing the Front End and Backend! ====================== =============================================================================== - Drupal speeding up is actually only a small part of load time, the real deal are your scripts/images/css - Measure to prove optimization success! - Measure overall load time? - Measure Page size? - Measure time until DOM is loaded... I like that, for JS1 - time until page is rendered, pretty close to when the dom is loaded - measure time until page is functional? - he says its the best metric, but also the most complicated - Tools - Firebugs Net panel - lets you inspect how long each GET takes - More about Yslow! - Yslow only measures how many images, etc, but not how long it takes your js to run. - AOL Page Test (webpagetest.org) - IBM Page Detailer (alphaworks.ibm.com/tech/pagedetailer - Pingdom (tools.pingdom.com) - Webkit's Web Inspector (Safari 4 or WeKit from webkit.org) - Web debugging proxies (charlesproxy.com, fiddlertool.com) see your website on slow connections - They display waterfall diagrams [start][connect][first byte][last byte] - [start] - tries to resolve domain name through DNS, opens up TCP connection - [connect] - figures out what the request is, and what to send (so processing) - [first byte and last byte] - actually sending the data back - MOST of the time is spent on the start and connect phases - so the number of requests is HUGE!!! - this is why we compress files together, its also why a simple html page loads fast as fuck. - sprites baby! - sophisticated aggregation: drupal.org/project/sf_cache - no redirects...? - USE A CDN!!! HE WILL POST THE SLIDES ONLINE! - static1.blah.com, static2.blah.com, static3.blah.com - parallelization (2 hosts = best) - stevesouders.com/ua - smushit.com - compresses files on the fly - LAZY JS! For PBT, I can use AJAX on the front end carousel, only loading one picture at a time! - USE InnoDB for sessions table, as well as watchdog! anything that gets alot of writes! - Op-code cache for PHP (big time improvements!) APC is the recommended one. Can't do on Mosso, right? - job_queue or queue_mail module! For sending mails on updates (notifications) ======================================================================================= ======================== CDN Integration - Wim Leers! ================================= ======================================================================================= Page loading performance - page rendering performance, its backend. - page loading performance is the time it takes to load the web page, which is backend (render) and front end. - 100ms of extra load causes 1% sales drop - 500ms causes 20% fewer searches! - 10-20% on loading html - 80-90% is the front end performance! This is what a CDN can help with! Key CDN Properties - Geographical spread (PoPs) - populating: Pull versus Push - Pull - virtually no setup, files transfered automatically, but you can't process files... - Push: ftp, sftp, rsync, webdav, amazon s3 - you have to set them up (boo!) - Lock-in factor - pull CDN, you can move from one to the other. CDN2 is a push! The CDN Effect: YSlow - yslow does not reflect the real-world page loading performance! Episodes - JS code that measures episodes of a web page's loading sequence. - has a firebug extension - breaks down load time by frontend and backend - measures the REAL WORLD page loading performance - he is writing a drupal module that integrates drupal with episodes Drupal + CDN - Change all code that calls base_path(): - common.inc - file.inc - theme.inc page.tpl.php - Cons: Very limited (can only use pull cdns) Simple CDN module - drupal.org/project/simplecdn - Immature, very limited, more dependencies Look for: - Episodes.module - CDN integration - daemon for synchronization to push cdns wimleers.com/talk/drupalcon-dc-2009 ============================================================================ ======================== Staging & Deployment ============================== ============================================================================ - DB Scripts module, take a dump of development and live site and merge them. - Traditional Deployment - everything is in code - mature tools to manage the code (svn, editors, command line dist. tools) - Code moves on way (dev -> qa -> prod) - Drupal Deployment - drupal stores a lot in the database!!! yeah! - Data moves both ways (dev/configuration starts in production and moves out, user generated content starts at prod and comes in) so can't just mysql dump from dev! - a real problem! - primary key issues - Options That Suck - develop on production (ME!) - repeat everything by hand at launch (sucks... and ME!) - If its configuration, it better be in code. - so... don't make your changes through the web based interface! - write update functions! - set variables manually (variable_set) - create nodes manually - set CCK image fields! - Macro module (part of devel), then record it and call drupal_execute! Tips to do this 1. Find the function that does the work. Call it! 2. Fake form submissions with macros. 3. Put things directly into the database (you lose hooks, messy) - Update functions are run alphabetically.... this can mess things up. - name modules zz_blah to make sure its called last! - Cons: it takes a while... - Make your update functions as you are doing the changes... - a module called sniff, it keeps track of variable changes so you can see how you break things! *** ANOTHER METHOD *** DBScripts! GOALS: - Keep the db in sync with code - Preserve ability to use the web GUI - Rapid development workflow ** yeah, ME TOO! *** - Merge development and production databases Filtering Tables - Ignore tables with useless data when dumping (sessions, watchdog, cache) - None (complete dump), Minimum (for production), Development (just give me useful stuff) - Preserve tables with useful data during restore - doesn't get rid of sessions, for instance Versions Tracked by Default - Development - Records development's modification - Last Merge - Tracks the state when development and production were in sync - Production - Stores current data contributed by users Keep Schemas in Sync - Force CCK fields to use their own table - how? (select as multiple, it creates its own table, unselect it as multiple, it stays... for 5.x) - create a junk content type to hold all fields...? - Run update.php before merging Table based merge - wholly use all data from a table of one version Data merge - compare data of each row from both versions and merge Options for handling auto increment IDs - use different ranges - set increment_increment and increment_offset for mysql - production does even, development does odd - apply core patch for each workspace drupal.org/project/dbscripts **How to use it!** -- Database Synchronization! - no magic bullet ====================================================== ====================== DAY 3! ======================== ====================================================== ==================== PROCESS! ======================== - this guy does what i do, except he's been doing it for 10 years! - Three Axioms - !Drupal != Bad Website - Druapl != Good Website - drupal with a good idea plan and execution, is better than not drupal with the same thing - Process = good plan and execution * Plan -> Design -> Develop -> Verify -> [Launch] Train -> Support - Kinda dated module... I mean, did I do this with PBT? - No, I did Plan -> Develop -> Design -> Develop -> Launch -> Train -> Verify -> Support - "Skip Intro" (too much focus on the presentation, leads to the long-term degradation of the website) - When the designer drives the process, thats where you have the long-term degradation. Which is why its good for me to drive the process! - When the developer drives... -> boxy/clunky, and disinterest to the user. Yeah! - New Process -> Designer + Developer drive the bus together! - Plan -> Design + Develop -> Verify -> Train -> Launch -> Train -> Support | | | | Wireframe Alpha Beta Launch wellstone.org - example! PROCESS --------------- 1. Strategic Brief -> Introduce the buesinesses to each other -> created by person on OUR end that initially contacts the client. Find out their goals, let them know what you do. - DOCUMENTED so that you can look back later 2. Kick-Off Meeting -> Introduce teams, build excitement, recap and clarify project goals. - get clients to talk to each other!!! Huge, so that they don't change their mind later. - Big, expensive meeting... shit. - We listen, we don't talk much. 3. Competitive Analysis -> check out the competition 4. Content Types -> Figure out how we are going to store information (the ingredients) - This is planning for me - DO THIS FOR SOLB! This is CRUCIAL because I will forget what my notes are! - literally break it down by types of content, it will help Selene! - when I email her, this is what I am sending! 5. Site Map approval by client (aka site architecture!) 6. Wireframes!! - AWESOME!!! Come up with the boxed layout of the website, placing your content from your site map within it. You do it for all types of pages, this helps the designer! - NOT TO SCALE, the designer will have freedom to change it, but to leave the structure in tact. - this way the designer and the developer can both work at the same time. - APPROVED BY THE CLIENT... HUGE!!! - I kinda did this for PBT, we wireframed it by looking at sites we wanted to copy - Once you get this part done, momentum is going good, you can hit the ground running 7. Design + Development - Design = Creative Brief (their colors, main audience, competition, what's unique?, key objectives, design directive (progressive, bold, clean and clear), Needs * Design process - start with the homepage? its OK to start with the homepage, because we have a wireframe to work from. * Development process - once you have the wireframe and the content types the development team can get straight to work. - ends in theming - Prototype Build - site skeleton (drupal core, contrib favorites) - minimalist theme (yahoo yui reset + drupal restoration) - database snapshot - SOMETHING I SHOULD STANDARDIZE ON MY OWN! - content types built - wireframes dissected for views - Zen theme + acquia drupal (good for site skeleton??) - Actual Content entry - verification & training - "Prototype" - a nasty looking site, basically what I do with Garland! 8. Theme it - show it as alpha - the client's last chance for feature requests - go to beta(feature freeze) - Beta feedback - Complete beta feedback (last opportunity for content change requests) - launch QA (code freeze/content freeze) - Delivery launch candidate - Client review - Launch - Training Manual - Training groups.drupal.org/projectManagement #drupalprocess on twitter - what do they use for wireframes -> done in Illustrator!! maybe use draw in open office ======================================================================================== ======================= Promiscuous Drupal (Drupal + Web APIs) ========================= ======================================================================================== - Drupal is one tool among many - Services - Spam filtering -> Mollom, Akismet - Searching -> Solr, Google, Acquia - Feed Generation -> Feedburner - Content tagging -> Calais, Times Tags - Authentication -> OpenID - Bulk Mail -> Mailchimp! - Images galleries -> Flickr - check out stackoverflow.com - look on the 3rd party integration category under drupal modules Farm out services that: - benefit from centralization (auth, ads) - require expertise (bulk mail) - Demand massive processing or sample data (fast indexing, spam filtering, auto-tagging) Taking it up a notch - Posting links? Use Delicious. - Photos and galleries? Use Flickr! - Shoutbox/short updates? Use Twitter. - Video? Youtube, Blip.tv, revver? revr? - Reviewing books? Amazon, Goodreads. - Comments? Disqus! - Blogging? Use Wordpress. Pull it in with the RSS feed. Become the crossroads, or enhance native content. When does it work? - heavily social sites - News sites - Personal Aggregators (FriendFeed, Tumblr) - External content is treated as something that lives _out there_ How? - Aggregator module - Activity module - DayLife API, NowPublic's new service - Native modules (delicious, flick, etc) programmableweb.com - APIs Writing your own - drupal_http_request() - PHP5 SimpleXML & JSON - drupal_write_record() - Expose your tables via Views - Wrap local vs. remote - See Building APIs that Rock (on drupalcon site) =============================================================================== ========================= The Drupal Redesign ================================= =============================================================================== - Usablity: can the user accomplish their goal? - User Experience (UX): - makes you WANT to use something, because its done well (muxtape) - think the iphone, its so good, i don't care that the service sucks. - good vibes! - user experience is a forest, its complex - usability is each individual tree - Define the audience - Design a System - it would be stupid to try and design every page in photoshop - all details are related to a whole (gives you the sense of "that feels nice") - Practical Example: the header - strategy - focus on search -> the "refine your search" is there to build trust - They created a style guide, primary colors, secondary colors, spacial references (padding, margin, button styles, icons) - Every element of the design has to relate to everything else... awesome. - Iterative & Incremental Design - the first couple of design iterations were pretty bare, they were kinda wireframes of the design. - check out silverback (application for...usability testing?) ********************************************************************************* ============================== Advanced Ubercart ================================ ================================================================================= - All examples are Drupal 6 & ubercart 2.0 (they are using a theme from topnotchthemes, its nice) * Selling File Downloads - 1 product node, multiple prices for different methods of delivery - Required modules: - Core Ubercart - File Downloads - Attributes (multiple variations of a single product) - WOW, we should be using Attributes for PBT...? Maybe... - SKU adjustments - assigns SKU based on what the customer chooses (from option attributes) - Features: - File Download - choose the SKU that should have a file download (so we choose Download and Download+DVD, but not DVD!) - override the shippable-ness with from here * Selling Node Access - uc_nodeaccess - lets you sell access to a PARTICULAR NODE on your site - content_access module to restrict node access to the node you want to sell - relies on ACL (I definitely looked into this for PBT) - uses content access to remove anonymous or authenticated user access - then clicks "per node access control" to be used with uc_nodeaccess - product feature -> node access -> grant access to any node on your site (start date + expiration!) - you can add an arbitrary number of features, so access to 10 different nodes... - furthermore, you can set the dates, so node 1 today, node 2 next week, etc which is a great way to setup online classes! - Also they use Role Access (uc_role) to assign Student role. - uc_restrict_quantity -> get rid of quantity!! good! * Event Registration!!!!! - uc_nodecheckout module - assign a node form to a product in your catalog!!! - CREATING UBERCAMPS -> multiple events, but one registration info - You make a node to handle registration information (collecting and storing it) - Registration CONTENT TYPE - redirected to node add form for registration content type (first name, last name, email, company, status, order) - status = "paid" or not - order = link to order - allow anon to create this content type - Node checkout settings (basically sensible defaults) - associate registration node type to the product - You can associate it with a single product - registration for multiple events - setup a view, return any published product node that is in the events category of the catelogue, select that as what you can register for (so all of your events) - Add to cart sends you to the Registration Add Node form - users can edit their node - THIS WILL DEFINITELY BE USEFUL FOR the nonprofit site I'm doing... whats that called? - Registration node gets filled out BEFORE completing checkout - SKU adjustment to specify certain tracks... look into this for that nonprofit! - Then you just create a view for your attendees!!! BAD FUCKING ASS! - Multiple events, same info needed per event. - how did he update the status? - they dropped workflow-ng - Conditional actions (trigger, conditions, actions) - Trigger: customer completes checkout - Conditions: in this case, none (so every time) - Actions: perform these -> custom PHP, look at orders, loop over products load the node that was stored, update status = complete, update order link - Actions rock. - Its best to move your actions out of the database and into code... but how? - Look into Actions in D6 for sure. =========================================================================================== =============================== Intro to SimpleTest ======================================= =========================================================================================== What is SimpleTest? - Works as expected, works as defined... - think of the expectations as a shopping list, you write your list BEFORE you go shopping What's a test? - Context -> Execute a certain action (simulate user clicking link, or submitting a form) -> Assertions (check that the output is what we want) Syntax to learn how SimpleTest works - Inform SimpleTest about your tets class MyModuleTestCase extends DrupalWebTestCase { function getInfo() { return array('name' => ... } } - set the context function setUp() { parent::setUp('my_module', 'my_module_dependency'); $permissions = array('use my module'); $ ... } - Test function testFunctionalityX() { // Go to a page and click on a link $this->drupalGet('my_module_page'); $this->clickLink(t('Hack core')); // check that we get results $this->assertText('Hack Kittens', t('missed it'); } -- doing it - create a ___.test file - extend DrupalWebTestCase Workflow - view the interface your are going to test - identify fields that you are going to submit information to (look at the names of the fields) - try it out yourself - duplicate in test - run it - visit admin/build/testing - select test - run Common Pitfalls - setup() and tearDown() methods, always call parent::setUp(); and parent::tearDown(); (setup first, teardown last) - submitting multi-form wizard $this->drupalPost('url', $edit, t('Submit')); // first page $this->drupalPost(NULL, ..) // stays on loaded page, so destination - use file_put_contents or $this->fail(print_r($edit, TRUE)) Core testing paradigm - no tests fail - tests required for new features, changes that do not have tests - focus on functional tests, not unit tests - testing pages/features not functions Lookup SimpleTest!!!!! Looks like it will save me some time. * Side note, check out Dates & Calendar module(s) for D6 * Mesh.com and explore (remote desktop!!!) ============================================================================================================= =================================== Token - The little API that could ======================================= ============================================================================================================= - tokens action module - Triggers allow you to setup... triggers for actions to respond to! - pathauto is the classic example of how you use tokens Consuming Tokens - two major functions: -> token_replace($original, $type = 'global', $object = NULL); -> token_replace_multiple($original, $types = array('user' => $account, 'node' => $node)); // replaces text with the global namespace, and also the user namespace (taking in the user) $replaced = token_replace_multiple($original, array('user' => $user, 'global' => NULL)); Providing Tokens - two main functions: -> hook_token_list($type = 'all'); - says "these are what we provide" -> hook_token_values($type, $object = NULL); - parses apart the object that is getting passed in - default to blank strings - provide regular and raw (filtered and raw) function tokenexample_token_list($type = 'all') { if ($type == 'node') { $tokens['node']['dawg'] = t('Something from pimp my ride'); return $tokens; // FUTURE (proposed) $tokens['node']['dawg'] = array('description' => 'blah', 'callback' => 'token_node_dawg'); } } function tokenexample_token_values($type, $object = NULL) { $tokens['node']['dawg'] = ''; if ($type == 'node') { $tokens['node']['dawg'] = check_plain($object->name); $tokens['node']['dawg'] = $object->name; } return $tokens; } // for the future! // we only call this function IF we need it... function token_node_dawg($object, $filter) { return $tokens['node']['dawg'] = checkplain($object->name); } Problems - generates all tokens every stinking time. WTF? - there is a caching mechanism... - scannability/discoverability drupal.org/node/113614 -> the future of token