View difference between Paste ID: 4fLC9FLy and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | WordPress Stay in Category |
2 | ||
3 | Author: Mac McDonald | |
4 | Contact: Use the Contact Us form under About on BlueGrassMiataClub =dot= com | |
5 | ||
6 | By default, the previous/next_post_link in single.php does not stay in | |
7 | category. If you view a category archive, then select a single post, | |
8 | the prev/next link may not show a post in the same category. | |
9 | ||
10 | If you set the 'in_same_cat' parameter to the previous/next_post_link | |
11 | calls in single.php to 'true', single.php will stay in category | |
12 | provided the posts belong only to one category. If posts belong to | |
13 | more than one category, the prev/next links may point to posts in one | |
14 | of the categories other than the one from the category | |
15 | archive. Changing 'in_same_cat' will also affect how a blog works, | |
16 | because you normally don't want to stay in category when coming from a | |
17 | blog post list. | |
18 | ||
19 | Solving this problem requires several steps: | |
20 | ||
21 | 1. Modify archive.php (or category.php, if it exists) to pass the | |
22 | 'stayincat' parameter in the URL of single posts. | |
23 | ||
24 | 2. Modify single.php to detect the 'stayincat' parameter, set a global | |
25 | category id for the use by following filters, and set the | |
26 | 'in_same_cat' to 'true' in previous/next_post_link. | |
27 | ||
28 | 3. Add filters for previous/next_post_join so that only the global | |
29 | category id is selected, instead of all categories for the current | |
30 | post. | |
31 | ||
32 | 4. Add filters for previous/next_post_link to pass the 'stayincat' | |
33 | parameter in the links to other single pages. | |
34 | ||
35 | 5. Add a replacement function for add_query_arg because it does not | |
36 | work on the links in the previous/next_post_link filters. | |
37 | ||
38 | Here is the code for archive.php (or category.php): | |
39 | ||
40 | <?php while (have_posts()) : the_post(); ?> | |
41 | <div <?php post_class() ?>> | |
42 | <?php $permalink = get_permalink(); // MAM modification to stay in category - see single.php | |
43 | if (is_category()) $permalink = add_query_arg('stayincat',get_query_var('cat'),$permalink); ?> | |
44 | <h3 id="post-<?php the_ID(); ?>"><a href="<?php echo $permalink; ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3> | |
45 | ||
46 | Here is the code for single.php: | |
47 | ||
48 | <div class="navigation"> | |
49 | <?php $mam_global_stay_in_cat = ($_GET['stayincat']) ? $_GET['stayincat'] : false; | |
50 | if ( $mam_global_stay_in_cat ) { ?> | |
51 | <div class="alignleft"><?php previous_post_link('« %link','%title',true) ?></div> | |
52 | <div class="alignright"><?php next_post_link('%link »','%title',true) ?></div> | |
53 | <?php } else { ?> | |
54 | <div class="alignleft"><?php previous_post_link('« %link') ?></div> | |
55 | <div class="alignright"><?php next_post_link('%link »') ?></div> | |
56 | <?php } ?> | |
57 | </div> | |
58 | ||
59 | And here are the filters and functions. They can go in functions.php, | |
60 | or at the top of single.php: | |
61 | ||
62 | // MAM - modification to stay in the category set in archive.php | |
63 | function mam_get_previous_post_join_filter ( $join, $in_same_cat = false, $excluded_categories = '' ) { | |
64 | global $mam_global_stay_in_cat; | |
65 | if ($mam_global_stay_in_cat) { | |
66 | $join = preg_replace('/tt.term_id IN \([^(]+\)/',"tt.term_id IN ($mam_global_stay_in_cat)",$join); | |
67 | } | |
68 | return $join; | |
69 | } | |
70 | function mam_get_next_post_join_filter ( $join, $in_same_cat = false, $excluded_categories = '' ) { | |
71 | global $mam_global_stay_in_cat; | |
72 | if ($mam_global_stay_in_cat) { | |
73 | $join = preg_replace('/tt.term_id IN \([^(]+\)/',"tt.term_id IN ($mam_global_stay_in_cat)",$join); | |
74 | } | |
75 | return $join; | |
76 | } | |
77 | function mam_previous_post_link_filter ($link='') { | |
78 | global $mam_global_stay_in_cat; | |
79 | //echo '<p>PREV LINK BEFORE:' . htmlspecialchars($link) . '</p>'; | |
80 | if ($mam_global_stay_in_cat && $link) { | |
81 | $link = mam_add_query_arg('stayincat',$mam_global_stay_in_cat,$link); | |
82 | //echo '<p>PREV LINK AFTER:' . htmlspecialchars($link) . '</p>'; | |
83 | } | |
84 | return $link; | |
85 | } | |
86 | function mam_next_post_link_filter ($link='') { | |
87 | global $mam_global_stay_in_cat; | |
88 | //echo '<p>NEXT LINK BEFORE:' . htmlspecialchars($link) . '</p>'; | |
89 | if ($mam_global_stay_in_cat && $link) { | |
90 | $link = mam_add_query_arg('stayincat',$mam_global_stay_in_cat,$link); | |
91 | //echo '<p>NEXT LINK AFTER:' . htmlspecialchars($link) . '</p>'; | |
92 | } | |
93 | return $link; | |
94 | } | |
95 | function mam_add_query_arg ($key,$value,$link) { | |
96 | // Adds the parameter $key=$value to $link, or replaces it if already there. | |
97 | // Necessary because add_query_arg fails on previous/next_post_link. | |
98 | if (strpos($link,'href')) { | |
99 | $hrefpat = '/(href *= *([\"\']?)([^\"\' ]+)\2)/'; | |
100 | } else { | |
101 | $hrefpat = '/(([\"\']?)(http([^\"\' ]+))\2)/'; | |
102 | } | |
103 | if (preg_match($hrefpat,$link,$matches)) { | |
104 | $url = $matches[3]; | |
105 | $newurl = add_query_arg($key,$value,$url); | |
106 | // echo '<p>OLDURL:' . htmlspecialchars($url) . '</p>'; | |
107 | // echo '<p>NEWURL:' . htmlspecialchars($newurl) . '</p>'; | |
108 | $link = str_replace($url,$newurl,$link); | |
109 | } | |
110 | ||
111 | return $link; | |
112 | } | |
113 | ||
114 | add_filter('get_previous_post_join','mam_get_previous_post_join_filter'); | |
115 | add_filter('get_next_post_join','mam_get_next_post_join_filter'); | |
116 | add_filter('previous_post_link','mam_previous_post_link_filter'); | |
117 | add_filter('next_post_link','mam_next_post_link_filter'); |