SlideShare a Scribd company logo
1 of 45
Advanced Post Queries
Best Practices for Accessing your
              Data

         @TomAuger
    WordCamp Montreal 2012
What's in the database?*
•   Posts                • Users
•   Pages                • User meta
•   Attachment records   • Site Options
•   Revisions               –   Your URL
•   Nav Menus               –   Widget settings
                            –   Theme options
•   Custom Post Types       –   User capabilities
•   Post Meta                   (maybe)
•   Categories
•   Tags
•   Custom Taxonomies
                         • * basically, everything
Post Queries in the URL
           (look Ma, no code!)

• Settings > Reading
    – "Your Latest Posts"       – / (index.php)
    – Front page                – /        (front-page.php)
    – Posts page                – /posts-page-slug/
•   Page / post slug        •   /post-or-page-slug/
•   Category Archive        •   /category/term/
•   Date                    •   /year/[month/]
•   Author Archive          •   /author/author-nicename/
•   post_type               •   /post-type-slug/
•   Search                  •   /search/term/
Post Queries (code)


•   query_posts( $args )
•   new WP_Query( $args )
•   get_posts( $args )
•   get_pages( $args )
And where does it go?



• Most often on the PHP page template
• Widgets defined in plugins
• Hooks declared in functions.php or include
query_posts() usage
                Old Skool


• Looks like URL query parameters
• Mimics the browser address, so may feel more familiar
• Kinda hard to read…


  query_posts( ‘cat=6&post_type=product&numberposts=5’ );
query_posts() usage
             The Cool Way…
• Supply arguments as array of key => value pairs
• Lots more brackets and stuff, but…
• Kinda looks cool once you get used to it




  query_posts( array(
         ‘cat’ => 6,
         ‘post_type’ => ‘product’,
         ‘posts_per_page’ => 5
  ) );
What can we query?
    http://codex.wordpress.org/Class_Reference/WP_Query


•   author                    • custom fields (meta)
•   category / tag / tax      • sticky
•   post name, ID(s)          • add pagination
•   page parent               • set sort order and
•   post type                   criteria
•   post status               • comment count
•   date & time               • even random posts!
query_posts Example
              Movie of the Day!

•   Create a new Page
•   Only the slug is important
•   Add query_posts() before any HTML
•   Current page content is clobbered
    query_posts( array (
           'orderby' => 'rand',
           'posts_per_page' => 1
    ) );


• http://localhost/projects/wordcamp/query_posts-example/
query_posts to Limit Page Count?
• Common example is to change # posts
  displayed
 query_posts( ‘posts_per_page=20’ );


• Loads the posts twice*!
• Consider Settings > Reading > Blog Pages
  Show At Most…

• * and then some…
What’s up with
                query_posts()?
• http://codex.wordpress.org/Function_Reference/query_posts

• Only useful for altering the Main Loop
• Can break pagination
   – (but can be fixed with effort)
• Still executes the original query!
   – (and then some)
• Don't use in a subquery!
Why Subqueries?


•   Add related posts
•   Add child pages
•   Add other types of content (eg: News)
•   Widgets!
Is there a template tag for that?
• http://codex.wordpress.org/Template_Tags

• Author info (the_author(),
  the_author_meta() )
• Metadata (the_meta() )
• Categories, tags
• Navigation (eg: next_post_link() )
Template Tag Example
• http://localhost/projects/wordcamp/template-tags/


• Inside "The Loop", powered by
  the_post()
  <div class="post-meta"><?php the_meta() ?></div>
  <div class="categories"><?php the_category(); ?></div>
  <div class="tags"><?php the_tags(); ?></div>

  <div class="nav">
         <?php previous_post_link() ?>
         |
         <?php next_post_link() ?>
  </div>
"Real" Sub-queries: WP_Query

• The brains behind all queries on the wp_posts
  table
• Defined in wp-includes/query.php
• All queries go through WP_Query
• "Get your own" with


 new WP_Query( $args );
WP_Query usage

<?php
  $my_sub_query = new WP_Query( array (
     'post_type' => 'quotes',
     'order' => 'rand',
     'posts_per_page' => 1
  ) );

    while ( $my_sub_query->have_posts() ){
      $my_sub_query->the_post();
      get_template_part( 'my_loop_template' );
    }

    wp_reset_postdata();
}
WP_Query Examples



• http://localhost/projects/wordcamp/date-query/

• http://localhost/projects/wordcamp/sort-by-post-meta/
Meta Queries

• Make your postmeta work (harder) for you!
• At first blush, a little funky

 <?php
  $meta_query = new WP_Query( array(
    'meta_query' => array(
       array(
         // meta query here
       )
     )
  ) );
More Meta Query Examples


• http://localhost/projects/wordcamp/meta-queries/

• http://localhost/projects/wordcamp/multiple-meta-queries-and/

• http://localhost/projects/wordcamp/multiple-meta-queries-or/
Taxonomy Queries

• As with meta_query, so with tax_query
  <?php
   $tax_query = new WP_Query( array(
     'taz_query' => array(
        array(

          )
      )
   ) );


• http://localhost/projects/wordcamp/tax-query-simple/
wp_reset_postdata()?

• If you use the_post(), clean up after
  yourself
• the_post() sets lots of $_GLOBALs
• Could break templates, footers, widgets
  etc…

• http://localhost/projects/wordcamp/wp_reset_postdata/
Global Query Manipulation
        (The Good Stuff!)



• Modify the Main Query
• Modify the way all queries work site-wide
• Modify queries for a specific page
Case Study: amovo.ca

•   Furniture retailer with multiple brands
•   Custom post type: "amovo-products"
•   Custom post type: "manufacturer"
•   Custom taxonomies: "product-categories"
    and "product-applications"

• http://localhost/projects/amovo/
amovo.ca: Custom Global Sort

• Wanted to "feature" certain products
• Wherever they might be listed
• eg:
  http://localhost/projects/amovo/product-
  categories/executive-conference-seating/

• Best match: custom field "_zg_priority"
amovo.ca: Category Archive



• Uses the standard custom tax query
• Need to ORDER BY wp_postmeta for ALL
  queries
Filter: 'posts_clauses'
• Allows us to manipulate SQL before it is
  sent to the database
• For ALL queries (not just main query)
 if (! is_admin()){
  add_filter(
   'posts_clauses', 'sort_by_priority', 10, 2
  );
 }

 function sort_by_product_priority( $clauses, $query ){
  global $wpdb;

  //… more to come
 }
Keeping it lean
• If query has nothing to do with products,
  don’t add the overhead
• Only affect product-related tax queries

 function sort_by_product_priority( $clauses, $query ){
   global $wpdb;

     if ( in_array( $query->query_vars['taxonomy'],
       array( 'product-category', 'product-application'))
     ){
        // …
     }
 }
Make sure it's the right query!

• These hooks affect EVERY query
• Add conditionals to reduce overhead
  – is_admin() during hook registration
  – is_main_query()
  – $query->query_vars (eg: "taxonomy",
    "post_type", "orderby")

if (
 'page-hijacking' == $query_obj->query_vars['pagename']
){ … }
JOIN your tables
• LEFT JOIN doesn't exclude missing meta
• Alias your JOINs to avoid collision
 function sort_by_product_priority( $clauses, $query ){
  global $wpdb;
     …
   // JOIN on postmeta to get priority
   $clauses['join'] .= "
      LEFT JOIN {$wpdb->postmeta} PM
        ON ({$wpdb->posts}.ID = PM.post_id
        AND PM.meta_key = '_zg_priority')
   ";
     …
  return $clauses;
 }
Modify ORDER BY
• PREPEND your sort criteria
• Don't forget to add comma if you need
  one!
 function sort_by_product_priority( $clauses, $query ){
      …
   $join .= "LEFT JOIN {$wpdb->postmeta} PM...";
      …
   $orderby = &$clauses['orderby']; // by reference!
   if (! empty( $orderby ) ) $orderby = ', ' . $orderby;

   $orderby = "
     IFNULL(P.meta_value, 5) ASC,
     {$wpdb->posts}.post_title ASC" . $orderby;

  return $clauses;
 }
Manipulating the Main Query
           (main filters)
• Manipulating the URI query variables
   – before the query is parsed
   – add_filter( 'request' )

• Manipulating the query object
   – before the SQL is generated
   – add_filter( 'parse_query' ) / 'pre_get_posts'

• Manipulating the SQL
   – before the SQL is run
   – add_filter( 'posts_clauses' ) 2 arguments

• Manipulating the results
   – before stickies and status
   – add_filter( 'posts_results' )
Case Study: Date Range

• WP_Query doesn't (currently) support date
  ranges
• Let's create 'before_date' and 'after_date'

 $date_query = new WP_Query( array(
        'after_date' => '2012-08-10',
        'before_date' => '2012-08-14'
 ) );
Exploiting the Query Object
add_filter( 'posts_where', 'date_ranges', 10, 2 );
function 'date_ranges( $where_clause, $query_obj ){
  global $wpdb;

    if ( $before_date = $query_obj->query['before_date'] ){
      $where_clause .= "
         AND {$wpdb->posts}.post_date < '{$before_date}'
      ";
    }

    if ( $after_date = $query_obj->query['after_date'] ) ){
      $where_clause .= "
         AND DATE({$wpdb->posts}.post_date) > '{$after_date}'
      ";
    }

    return $where_clause;
}
Improvements & Security
• Make sure we're actually getting a Date
• Cast the time() object to a mySQL DATE
  string
• Cast mySQL TIMESTAMP to DATE portion
  only
if ( $after_date = strtotime(
  $query_obj->query['after_date']
) ){
  $after_date = date( 'Y-m-d', $after_date );
  $where_clause .= "
     AND DATE({$wpdb->posts}.post_date) > '{$after_date}'
  ";
}
Conclusions

•   TMTOWTDI
•   Go as high-level as you can
•   Use query_posts() sparingly
•   wp_reset_postdata()!
•   Modify the Main Query with filters / actions

• Make WordPress sing!
Working with $wpdb
• global $wpdb
• Always use $wpdb->table_name
• Always use $wpdb->prepare with tainted
  data
• Use the right get_* method for the job
  – get_var()
  – get_row()
  – get_col()
  – get_results()
Please avoid inserting /
              updating…
•   Posts
•   Users
•   Meta data (usermeta or postmeta)
•   Options
•   Taxonomies and Terms (especially!)

• Basically, if there's a default wp_* table, there
  are core methods for inserting, updating and
  deleting
When to extend schema

• Primary object has tons of metadata
• Highly relational data
• Plugin tables (be sure to offer DROP
  option!)
  – register_deactivation_hook();
• Can't map to post, meta and taxonomy
Final observations… 'n stuff

• There are actually very few reasons to
  generate your own SQL
• There's probably a core function for that
• Due diligence and research
  – Google search "wordpress [keywords]"!
  – Get a good IDE (Jer's talk about NetBeans!)
Thank You!
updates: @TomAuger
 www.tomauger.com
Extra Slides




• Ah, time is thy enemy…
More Template Tags


<div class="author-info">
  <p><strong>Posted by: </strong>
  <?php the_author(); ?>
  (<?php the_author_meta( 'first_name' ) ?>
  <?php the_author_meta( 'last_name' ) ?>)

  <?php echo apply_filters(
    'the_content', get_the_author_meta( 'description' )
  ); ?>
</div>
Anatomy of a Query
• $wp->main() is called after everything is loaded
    – Parses the browser query string and applies rewrite rules
    – Rebuilds the query string for main query
    – Runs get_posts() on the main $wp_the_query (WP_Query instance)
• WP_Query then
    – Reparses the query string
         • Request for single page short-circuits and uses cache if possible
    –   Parses the search
    –   Parses any taxonomy queries
    –   Generates the SQL clauses
    –   Gives cacheing plugins a chance to get involved
    –   Generates the SQL request and executes it!
    –   Processes comments
    –   Processes stickies
    –   Updates caches
Plugin Authors


• Consider require_once( wp-admin/install-
  helper.php ) within your
  register_activation_hook()
  – helper functions like maybe_create_table(),
    maybe_add_column()

More Related Content

Recently uploaded

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 

Featured

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Advanced Post Queries

  • 1. Advanced Post Queries Best Practices for Accessing your Data @TomAuger WordCamp Montreal 2012
  • 2. What's in the database?* • Posts • Users • Pages • User meta • Attachment records • Site Options • Revisions – Your URL • Nav Menus – Widget settings – Theme options • Custom Post Types – User capabilities • Post Meta (maybe) • Categories • Tags • Custom Taxonomies • * basically, everything
  • 3. Post Queries in the URL (look Ma, no code!) • Settings > Reading – "Your Latest Posts" – / (index.php) – Front page – / (front-page.php) – Posts page – /posts-page-slug/ • Page / post slug • /post-or-page-slug/ • Category Archive • /category/term/ • Date • /year/[month/] • Author Archive • /author/author-nicename/ • post_type • /post-type-slug/ • Search • /search/term/
  • 4. Post Queries (code) • query_posts( $args ) • new WP_Query( $args ) • get_posts( $args ) • get_pages( $args )
  • 5. And where does it go? • Most often on the PHP page template • Widgets defined in plugins • Hooks declared in functions.php or include
  • 6. query_posts() usage Old Skool • Looks like URL query parameters • Mimics the browser address, so may feel more familiar • Kinda hard to read… query_posts( ‘cat=6&post_type=product&numberposts=5’ );
  • 7. query_posts() usage The Cool Way… • Supply arguments as array of key => value pairs • Lots more brackets and stuff, but… • Kinda looks cool once you get used to it query_posts( array( ‘cat’ => 6, ‘post_type’ => ‘product’, ‘posts_per_page’ => 5 ) );
  • 8. What can we query? http://codex.wordpress.org/Class_Reference/WP_Query • author • custom fields (meta) • category / tag / tax • sticky • post name, ID(s) • add pagination • page parent • set sort order and • post type criteria • post status • comment count • date & time • even random posts!
  • 9. query_posts Example Movie of the Day! • Create a new Page • Only the slug is important • Add query_posts() before any HTML • Current page content is clobbered query_posts( array ( 'orderby' => 'rand', 'posts_per_page' => 1 ) ); • http://localhost/projects/wordcamp/query_posts-example/
  • 10. query_posts to Limit Page Count? • Common example is to change # posts displayed query_posts( ‘posts_per_page=20’ ); • Loads the posts twice*! • Consider Settings > Reading > Blog Pages Show At Most… • * and then some…
  • 11. What’s up with query_posts()? • http://codex.wordpress.org/Function_Reference/query_posts • Only useful for altering the Main Loop • Can break pagination – (but can be fixed with effort) • Still executes the original query! – (and then some) • Don't use in a subquery!
  • 12. Why Subqueries? • Add related posts • Add child pages • Add other types of content (eg: News) • Widgets!
  • 13. Is there a template tag for that? • http://codex.wordpress.org/Template_Tags • Author info (the_author(), the_author_meta() ) • Metadata (the_meta() ) • Categories, tags • Navigation (eg: next_post_link() )
  • 14. Template Tag Example • http://localhost/projects/wordcamp/template-tags/ • Inside "The Loop", powered by the_post() <div class="post-meta"><?php the_meta() ?></div> <div class="categories"><?php the_category(); ?></div> <div class="tags"><?php the_tags(); ?></div> <div class="nav"> <?php previous_post_link() ?> | <?php next_post_link() ?> </div>
  • 15. "Real" Sub-queries: WP_Query • The brains behind all queries on the wp_posts table • Defined in wp-includes/query.php • All queries go through WP_Query • "Get your own" with new WP_Query( $args );
  • 16. WP_Query usage <?php $my_sub_query = new WP_Query( array ( 'post_type' => 'quotes', 'order' => 'rand', 'posts_per_page' => 1 ) ); while ( $my_sub_query->have_posts() ){ $my_sub_query->the_post(); get_template_part( 'my_loop_template' ); } wp_reset_postdata(); }
  • 17. WP_Query Examples • http://localhost/projects/wordcamp/date-query/ • http://localhost/projects/wordcamp/sort-by-post-meta/
  • 18. Meta Queries • Make your postmeta work (harder) for you! • At first blush, a little funky <?php $meta_query = new WP_Query( array( 'meta_query' => array( array( // meta query here ) ) ) );
  • 19. More Meta Query Examples • http://localhost/projects/wordcamp/meta-queries/ • http://localhost/projects/wordcamp/multiple-meta-queries-and/ • http://localhost/projects/wordcamp/multiple-meta-queries-or/
  • 20. Taxonomy Queries • As with meta_query, so with tax_query <?php $tax_query = new WP_Query( array( 'taz_query' => array( array( ) ) ) ); • http://localhost/projects/wordcamp/tax-query-simple/
  • 21. wp_reset_postdata()? • If you use the_post(), clean up after yourself • the_post() sets lots of $_GLOBALs • Could break templates, footers, widgets etc… • http://localhost/projects/wordcamp/wp_reset_postdata/
  • 22. Global Query Manipulation (The Good Stuff!) • Modify the Main Query • Modify the way all queries work site-wide • Modify queries for a specific page
  • 23. Case Study: amovo.ca • Furniture retailer with multiple brands • Custom post type: "amovo-products" • Custom post type: "manufacturer" • Custom taxonomies: "product-categories" and "product-applications" • http://localhost/projects/amovo/
  • 24. amovo.ca: Custom Global Sort • Wanted to "feature" certain products • Wherever they might be listed • eg: http://localhost/projects/amovo/product- categories/executive-conference-seating/ • Best match: custom field "_zg_priority"
  • 25. amovo.ca: Category Archive • Uses the standard custom tax query • Need to ORDER BY wp_postmeta for ALL queries
  • 26. Filter: 'posts_clauses' • Allows us to manipulate SQL before it is sent to the database • For ALL queries (not just main query) if (! is_admin()){ add_filter( 'posts_clauses', 'sort_by_priority', 10, 2 ); } function sort_by_product_priority( $clauses, $query ){ global $wpdb; //… more to come }
  • 27. Keeping it lean • If query has nothing to do with products, don’t add the overhead • Only affect product-related tax queries function sort_by_product_priority( $clauses, $query ){ global $wpdb; if ( in_array( $query->query_vars['taxonomy'], array( 'product-category', 'product-application')) ){ // … } }
  • 28. Make sure it's the right query! • These hooks affect EVERY query • Add conditionals to reduce overhead – is_admin() during hook registration – is_main_query() – $query->query_vars (eg: "taxonomy", "post_type", "orderby") if ( 'page-hijacking' == $query_obj->query_vars['pagename'] ){ … }
  • 29. JOIN your tables • LEFT JOIN doesn't exclude missing meta • Alias your JOINs to avoid collision function sort_by_product_priority( $clauses, $query ){ global $wpdb; … // JOIN on postmeta to get priority $clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} PM ON ({$wpdb->posts}.ID = PM.post_id AND PM.meta_key = '_zg_priority') "; … return $clauses; }
  • 30. Modify ORDER BY • PREPEND your sort criteria • Don't forget to add comma if you need one! function sort_by_product_priority( $clauses, $query ){ … $join .= "LEFT JOIN {$wpdb->postmeta} PM..."; … $orderby = &$clauses['orderby']; // by reference! if (! empty( $orderby ) ) $orderby = ', ' . $orderby; $orderby = " IFNULL(P.meta_value, 5) ASC, {$wpdb->posts}.post_title ASC" . $orderby; return $clauses; }
  • 31. Manipulating the Main Query (main filters) • Manipulating the URI query variables – before the query is parsed – add_filter( 'request' ) • Manipulating the query object – before the SQL is generated – add_filter( 'parse_query' ) / 'pre_get_posts' • Manipulating the SQL – before the SQL is run – add_filter( 'posts_clauses' ) 2 arguments • Manipulating the results – before stickies and status – add_filter( 'posts_results' )
  • 32. Case Study: Date Range • WP_Query doesn't (currently) support date ranges • Let's create 'before_date' and 'after_date' $date_query = new WP_Query( array( 'after_date' => '2012-08-10', 'before_date' => '2012-08-14' ) );
  • 33. Exploiting the Query Object add_filter( 'posts_where', 'date_ranges', 10, 2 ); function 'date_ranges( $where_clause, $query_obj ){ global $wpdb; if ( $before_date = $query_obj->query['before_date'] ){ $where_clause .= " AND {$wpdb->posts}.post_date < '{$before_date}' "; } if ( $after_date = $query_obj->query['after_date'] ) ){ $where_clause .= " AND DATE({$wpdb->posts}.post_date) > '{$after_date}' "; } return $where_clause; }
  • 34. Improvements & Security • Make sure we're actually getting a Date • Cast the time() object to a mySQL DATE string • Cast mySQL TIMESTAMP to DATE portion only if ( $after_date = strtotime( $query_obj->query['after_date'] ) ){ $after_date = date( 'Y-m-d', $after_date ); $where_clause .= " AND DATE({$wpdb->posts}.post_date) > '{$after_date}' "; }
  • 35. Conclusions • TMTOWTDI • Go as high-level as you can • Use query_posts() sparingly • wp_reset_postdata()! • Modify the Main Query with filters / actions • Make WordPress sing!
  • 36. Working with $wpdb • global $wpdb • Always use $wpdb->table_name • Always use $wpdb->prepare with tainted data • Use the right get_* method for the job – get_var() – get_row() – get_col() – get_results()
  • 37. Please avoid inserting / updating… • Posts • Users • Meta data (usermeta or postmeta) • Options • Taxonomies and Terms (especially!) • Basically, if there's a default wp_* table, there are core methods for inserting, updating and deleting
  • 38. When to extend schema • Primary object has tons of metadata • Highly relational data • Plugin tables (be sure to offer DROP option!) – register_deactivation_hook(); • Can't map to post, meta and taxonomy
  • 39. Final observations… 'n stuff • There are actually very few reasons to generate your own SQL • There's probably a core function for that • Due diligence and research – Google search "wordpress [keywords]"! – Get a good IDE (Jer's talk about NetBeans!)
  • 40. Thank You! updates: @TomAuger www.tomauger.com
  • 41.
  • 42. Extra Slides • Ah, time is thy enemy…
  • 43. More Template Tags <div class="author-info"> <p><strong>Posted by: </strong> <?php the_author(); ?> (<?php the_author_meta( 'first_name' ) ?> <?php the_author_meta( 'last_name' ) ?>) <?php echo apply_filters( 'the_content', get_the_author_meta( 'description' ) ); ?> </div>
  • 44. Anatomy of a Query • $wp->main() is called after everything is loaded – Parses the browser query string and applies rewrite rules – Rebuilds the query string for main query – Runs get_posts() on the main $wp_the_query (WP_Query instance) • WP_Query then – Reparses the query string • Request for single page short-circuits and uses cache if possible – Parses the search – Parses any taxonomy queries – Generates the SQL clauses – Gives cacheing plugins a chance to get involved – Generates the SQL request and executes it! – Processes comments – Processes stickies – Updates caches
  • 45. Plugin Authors • Consider require_once( wp-admin/install- helper.php ) within your register_activation_hook() – helper functions like maybe_create_table(), maybe_add_column()