<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[15819] trunk/wp-includes: Custom post type archives, second pass.</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/15819">15819</a></dd>
<dt>Author</dt> <dd>nacin</dd>
<dt>Date</dt> <dd>2010-10-15 19:44:57 +0000 (Fri, 15 Oct 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>Custom post type archives, second pass. see <a href="http://trac.wordpress.org/ticket/13818">#13818</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludesgeneraltemplatephp">trunk/wp-includes/general-template.php</a></li>
<li><a href="#trunkwpincludeslinktemplatephp">trunk/wp-includes/link-template.php</a></li>
<li><a href="#trunkwpincludesposttemplatephp">trunk/wp-includes/post-template.php</a></li>
<li><a href="#trunkwpincludespostphp">trunk/wp-includes/post.php</a></li>
<li><a href="#trunkwpincludesqueryphp">trunk/wp-includes/query.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludesgeneraltemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/general-template.php (15818 => 15819)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/general-template.php        2010-10-15 14:53:55 UTC (rev 15818)
+++ trunk/wp-includes/general-template.php        2010-10-15 19:44:57 UTC (rev 15819)
</span><span class="lines">@@ -547,6 +547,10 @@
</span><span class="cx">                 $title = $author-&gt;display_name;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        // If there's a post type archive
+        if ( is_post_type_archive() )
+                $title = post_type_archive_title( '', false );
+
</ins><span class="cx">         // If there's a month
</span><span class="cx">         if ( is_archive() &amp;&amp; !empty($m) ) {
</span><span class="cx">                 $my_year = substr($m, 0, 4);
</span><span class="lines">@@ -611,7 +615,6 @@
</span><span class="cx">  * be a space, the parameter value will need to have it at the end.
</span><span class="cx">  *
</span><span class="cx">  * @since 0.71
</span><del>- * @uses $wpdb
</del><span class="cx">  *
</span><span class="cx">  * @param string $prefix Optional. What to display before the title.
</span><span class="cx">  * @param bool $display Optional, default is true. Whether to display or retrieve title.
</span><span class="lines">@@ -636,6 +639,32 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+ * Display or retrieve title for a post type archive.
+ *
+ * This is optimized for archive.php and archive-{$post_type}.php template files
+ * for displaying the title of the post type.
+ *
+ * @since 3.1.0
+ *
+ * @param string $prefix Optional. What to display before the title.
+ * @param bool $display Optional, default is true. Whether to display or retrieve title.
+ * @return string|null Title when retrieving, null when displaying or failure.
+ */
+function post_type_archive_title() {
+        if ( ! is_post_type_archive() )
+                return;
+
+        
+        $post_type_obj = get_post_type_object( get_query_var( 'post_type' ) );
+        $title = apply_filters('post_type_archive_title', $post_type_obj-&gt;labels-&gt;name );
+
+        if ( $display )
+                echo $prefix . $title;
+        else
+                return $title;
+}
+        
+/**
</ins><span class="cx">  * Display or retrieve page title for category archive.
</span><span class="cx">  *
</span><span class="cx">  * This is useful for category template file or files, because it is optimized
</span></span></pre></div>
<a id="trunkwpincludeslinktemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/link-template.php (15818 => 15819)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/link-template.php        2010-10-15 14:53:55 UTC (rev 15818)
+++ trunk/wp-includes/link-template.php        2010-10-15 19:44:57 UTC (rev 15819)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx">                 $string = untrailingslashit($string);
</span><span class="cx"> 
</span><span class="cx">         // Note that $type_of_url can be one of following:
</span><del>-        // single, single_trackback, single_feed, single_paged, feed, category, page, year, month, day, paged
</del><ins>+        // single, single_trackback, single_feed, single_paged, feed, category, page, year, month, day, paged, post_type_archive
</ins><span class="cx">         $string = apply_filters('user_trailingslashit', $string, $type_of_url);
</span><span class="cx">         return $string;
</span><span class="cx"> }
</span><span class="lines">@@ -825,6 +825,63 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+ * Retrieve the permalink for a post type archive.
+ *
+ * @since 3.1.0
+ *
+ * @param string $post_type Post type
+ * @return string
+ */
+function get_post_type_archive_link( $post_type ) {
+        global $wp_rewrite;
+        if ( ! $post_type_obj = get_post_type_object( $post_type ) )
+                return false;
+
+        if ( ! is_array( $post_type_obj-&gt;rewrite ) || false === $post_type_obj-&gt;rewrite['archive'] )
+                return false;
+
+        if ( get_option( 'permalink_structure' ) ) {
+                $struct = ( true === $post_type_obj-&gt;rewrite['archive'] ) ? $post_type_obj-&gt;rewrite['slug'] : $post_type_obj-&gt;rewrite['archive'];
+                if ( $post_type_obj-&gt;rewrite['with_front'] )
+                        $struct = $wp_rewrite-&gt;front . $struct;
+                $link = home_url( user_trailingslashit( $struct, 'post_type_archive' ) );
+        } else {
+                $link = home_url( '?post_type=' . $post_type );
+        }
+
+        return apply_filters( 'post_type_archive_link', $link, $post_type );
+}
+
+/**
+ * Retrieve the permalink for a post type archive feed.
+ *
+ * @since 3.1.0
+ *
+ * @param string $post_type Post type
+ * @param string $feed Optional. Feed type 
+ * @return string
+ */        
+function get_post_type_archive_feed_link( $post_type, $feed = '' ) {
+        $default_feed = get_default_feed();
+        if ( empty( $feed ) )
+                $feed = $default_feed;
+
+        if ( ! $link = get_post_type_archive_link( $post_type ) )
+                return false;
+        $post_type_obj = get_post_type_object( $post_type );
+        if ( $post_type_obj-&gt;rewrite['feeds'] &amp;&amp; get_option( 'permalink_structure' ) ) {
+                $link = trailingslashit($link);
+                $link .= 'feed/';
+                if ( $feed != $default_feed )
+                        $link .= &quot;$feed/&quot;;
+        } else {
+                $link = add_query_arg( 'feed', $feed, $link );
+        }
+
+        return apply_filters( 'post_type_archive_feed_link', $link, $feed );
+}
+
+/**
</ins><span class="cx">  * Retrieve edit posts link for post.
</span><span class="cx">  *
</span><span class="cx">  * Can be used within the WordPress loop or outside of it. Can be used with
</span></span></pre></div>
<a id="trunkwpincludesposttemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/post-template.php (15818 => 15819)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/post-template.php        2010-10-15 14:53:55 UTC (rev 15818)
+++ trunk/wp-includes/post-template.php        2010-10-15 19:44:57 UTC (rev 15819)
</span><span class="lines">@@ -407,7 +407,10 @@
</span><span class="cx">                         $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
</span><span class="cx">                 }
</span><span class="cx">         } elseif ( is_archive() ) {
</span><del>-                if ( is_author() ) {
</del><ins>+                if ( is_post_type_archive() ) {
+                        $classes[] = 'post-type-archive';
+                        $classes[] = 'post-type-archive-' . sanitize_html_class( get_query_var( 'post_type' ) );
+                } else if ( is_author() ) {
</ins><span class="cx">                         $author = $wp_query-&gt;get_queried_object();
</span><span class="cx">                         $classes[] = 'author';
</span><span class="cx">                         $classes[] = 'author-' . sanitize_html_class( $author-&gt;user_nicename , $author-&gt;ID );
</span><span class="lines">@@ -472,6 +475,8 @@
</span><span class="cx">                         $classes[] = 'author-paged-' . $page;
</span><span class="cx">                 elseif ( is_search() )
</span><span class="cx">                         $classes[] = 'search-paged-' . $page;
</span><ins>+                elseif ( is_post_type_archive() )
+                        $classes[] = 'post-type-paged-' . $page;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if ( !empty( $class ) ) {
</span></span></pre></div>
<a id="trunkwpincludespostphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/post.php (15818 => 15819)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/post.php        2010-10-15 14:53:55 UTC (rev 15818)
+++ trunk/wp-includes/post.php        2010-10-15 19:44:57 UTC (rev 15819)
</span><span class="lines">@@ -924,7 +924,7 @@
</span><span class="cx">                 if ( !isset($args-&gt;rewrite['archive']) )
</span><span class="cx">                         $args-&gt;rewrite['archive'] = false;
</span><span class="cx">                 if ( !isset($args-&gt;rewrite['feeds']) || !$args-&gt;rewrite['archive'] )
</span><del>-                        $args-&gt;rewrite['feeds'] = false;
</del><ins>+                        $args-&gt;rewrite['feeds'] = (bool) $args-&gt;rewrite['archive'];
</ins><span class="cx"> 
</span><span class="cx">                 if ( $args-&gt;hierarchical )
</span><span class="cx">                         $wp_rewrite-&gt;add_rewrite_tag(&quot;%$post_type%&quot;, '(.+?)', $args-&gt;query_var ? &quot;{$args-&gt;query_var}=&quot; : &quot;post_type=$post_type&amp;name=&quot;);
</span></span></pre></div>
<a id="trunkwpincludesqueryphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/query.php (15818 => 15819)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/query.php        2010-10-15 14:53:55 UTC (rev 15818)
+++ trunk/wp-includes/query.php        2010-10-15 19:44:57 UTC (rev 15819)
</span><span class="lines">@@ -121,6 +121,22 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+ * Is the query for a post type archive page?
+ *
+ * @see WP_Query::is_post_type_archive()
+ * @since 3.1.0
+ * @uses $wp_query
+ *
+ * @param mixed $post_types Optional. Post type or array of posts types to check against.
+ * @return bool
+ */
+function is_post_type_archive( $post_types = '' ) {
+        global $wp_query;
+
+        return $wp_query-&gt;is_post_type_archive( $post_types );
+}
+        
+/**
</ins><span class="cx">  * Is the query for an attachment page?
</span><span class="cx">  *
</span><span class="cx">  * @see WP_Query::is_attachment()
</span><span class="lines">@@ -1041,6 +1057,15 @@
</span><span class="cx">         var $is_posts_page = false;
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * Set if query is for a post type archive.
+         *
+         * @since 3.1.0
+         * @access public
+         * @var bool
+         */
+        var $is_post_type_archive = false;
+
+        /**
</ins><span class="cx">          * Resets query flags to false.
</span><span class="cx">          *
</span><span class="cx">          * The query flags are what page info WordPress was able to figure out.
</span><span class="lines">@@ -1075,6 +1100,7 @@
</span><span class="cx">                 $this-&gt;is_singular = false;
</span><span class="cx">                 $this-&gt;is_robots = false;
</span><span class="cx">                 $this-&gt;is_posts_page = false;
</span><ins>+                $this-&gt;is_post_type_archive = false;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /**
</span><span class="lines">@@ -1234,7 +1260,7 @@
</span><span class="cx">                         $this-&gt;is_page = true;
</span><span class="cx">                         $this-&gt;is_single = false;
</span><span class="cx">                 } else {
</span><del>-                // Look for archive queries.  Dates, categories, authors, search.
</del><ins>+                // Look for archive queries.  Dates, categories, authors, search, post type archives.
</ins><span class="cx"> 
</span><span class="cx">                         if ( !empty($qv['s']) ) {
</span><span class="cx">                                 $this-&gt;is_search = true;
</span><span class="lines">@@ -1306,10 +1332,13 @@
</span><span class="cx">                         if ( '' != $qv['author_name'] )
</span><span class="cx">                                 $this-&gt;is_author = true;
</span><span class="cx"> 
</span><del>-                        if ( !empty( $qv['post_type'] ) )
-                                $this-&gt;is_archive = true;
</del><ins>+                        if ( !empty( $qv['post_type'] ) &amp;&amp; ! is_array( $qv['post_type'] ) ) {
+                                $post_type_obj = get_post_type_object( $qv['post_type'] );
+                                if ( is_array( $post_type_obj-&gt;rewrite ) &amp;&amp; $post_type_obj-&gt;rewrite['archive'] )
+                                        $this-&gt;is_post_type_archive = true;
+                        }
</ins><span class="cx"> 
</span><del>-                        if ( $this-&gt;is_date || $this-&gt;is_author || $this-&gt;is_category || $this-&gt;is_tag || $this-&gt;is_tax )
</del><ins>+                        if ( $this-&gt;is_post_type_archive || $this-&gt;is_date || $this-&gt;is_author || $this-&gt;is_category || $this-&gt;is_tag || $this-&gt;is_tax )
</ins><span class="cx">                                 $this-&gt;is_archive = true;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="lines">@@ -2636,6 +2665,26 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * Is the query for a post type archive page?
+         *
+         * @since 3.1.0
+         *
+         * @param mixed $post_types Optional. Post type or array of posts types to check against.
+         * @return bool
+         */
+        function is_post_type_archive( $post_types = '' ) {
+                if ( empty( $post_types ) || !$this-&gt;is_post_type_archive )
+                        return (bool) $this-&gt;is_post_type_archive;
+
+                if ( ! isset( $this-&gt;posts[0] ) )
+                        return false;
+
+                $post = $this-&gt;posts[0];
+
+                return in_array( $post-&gt;post_type, (array) $post_types );
+        }
+
+        /**
</ins><span class="cx">          * Is the query for an attachment page?
</span><span class="cx">          *
</span><span class="cx">          * @since 3.1.0
</span></span></pre>
</div>
</div>

</body>
</html>