PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/msw/dev/wp-includes/post-template.php

https://github.com/chrissiebrodigan/USC
PHP | 1232 lines | 654 code | 165 blank | 413 comment | 193 complexity | dd8fa2f84d391692ac8b267776b38d90 MD5 | raw file
  1. <?php
  2. /**
  3. * WordPress Post Template Functions.
  4. *
  5. * Gets content for the current post in the loop.
  6. *
  7. * @package WordPress
  8. * @subpackage Template
  9. */
  10. /**
  11. * Display the ID of the current item in the WordPress Loop.
  12. *
  13. * @since 0.71
  14. * @uses $id
  15. */
  16. function the_ID() {
  17. global $id;
  18. echo $id;
  19. }
  20. /**
  21. * Retrieve the ID of the current item in the WordPress Loop.
  22. *
  23. * @since 2.1.0
  24. * @uses $id
  25. *
  26. * @return unknown
  27. */
  28. function get_the_ID() {
  29. global $id;
  30. return $id;
  31. }
  32. /**
  33. * Display or retrieve the current post title with optional content.
  34. *
  35. * @since 0.71
  36. *
  37. * @param string $before Optional. Content to prepend to the title.
  38. * @param string $after Optional. Content to append to the title.
  39. * @param bool $echo Optional, default to true.Whether to display or return.
  40. * @return null|string Null on no title. String if $echo parameter is false.
  41. */
  42. function the_title($before = '', $after = '', $echo = true) {
  43. $title = get_the_title();
  44. if ( strlen($title) == 0 )
  45. return;
  46. $title = $before . $title . $after;
  47. if ( $echo )
  48. echo $title;
  49. else
  50. return $title;
  51. }
  52. /**
  53. * Sanitize the current title when retrieving or displaying.
  54. *
  55. * Works like {@link the_title()}, except the parameters can be in a string or
  56. * an array. See the function for what can be override in the $args parameter.
  57. *
  58. * The title before it is displayed will have the tags stripped and {@link
  59. * esc_attr()} before it is passed to the user or displayed. The default
  60. * as with {@link the_title()}, is to display the title.
  61. *
  62. * @since 2.3.0
  63. *
  64. * @param string|array $args Optional. Override the defaults.
  65. * @return string|null Null on failure or display. String when echo is false.
  66. */
  67. function the_title_attribute( $args = '' ) {
  68. $title = get_the_title();
  69. if ( strlen($title) == 0 )
  70. return;
  71. $defaults = array('before' => '', 'after' => '', 'echo' => true);
  72. $r = wp_parse_args($args, $defaults);
  73. extract( $r, EXTR_SKIP );
  74. $title = $before . $title . $after;
  75. $title = esc_attr(strip_tags($title));
  76. if ( $echo )
  77. echo $title;
  78. else
  79. return $title;
  80. }
  81. /**
  82. * Retrieve post title.
  83. *
  84. * If the post is protected and the visitor is not an admin, then "Protected"
  85. * will be displayed before the post title. If the post is private, then
  86. * "Private" will be located before the post title.
  87. *
  88. * @since 0.71
  89. *
  90. * @param int $id Optional. Post ID.
  91. * @return string
  92. */
  93. function get_the_title( $id = 0 ) {
  94. $post = &get_post($id);
  95. $title = isset($post->post_title) ? $post->post_title : '';
  96. $id = isset($post->ID) ? $post->ID : (int) $id;
  97. if ( !is_admin() ) {
  98. if ( !empty($post->post_password) ) {
  99. $protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
  100. $title = sprintf($protected_title_format, $title);
  101. } else if ( isset($post->post_status) && 'private' == $post->post_status ) {
  102. $private_title_format = apply_filters('private_title_format', __('Private: %s'));
  103. $title = sprintf($private_title_format, $title);
  104. }
  105. }
  106. return apply_filters( 'the_title', $title, $id );
  107. }
  108. /**
  109. * Display the Post Global Unique Identifier (guid).
  110. *
  111. * The guid will appear to be a link, but should not be used as an link to the
  112. * post. The reason you should not use it as a link, is because of moving the
  113. * blog across domains.
  114. *
  115. * @since 1.5.0
  116. *
  117. * @param int $id Optional. Post ID.
  118. */
  119. function the_guid( $id = 0 ) {
  120. echo get_the_guid($id);
  121. }
  122. /**
  123. * Retrieve the Post Global Unique Identifier (guid).
  124. *
  125. * The guid will appear to be a link, but should not be used as an link to the
  126. * post. The reason you should not use it as a link, is because of moving the
  127. * blog across domains.
  128. *
  129. * @since 1.5.0
  130. *
  131. * @param int $id Optional. Post ID.
  132. * @return string
  133. */
  134. function get_the_guid( $id = 0 ) {
  135. $post = &get_post($id);
  136. return apply_filters('get_the_guid', $post->guid);
  137. }
  138. /**
  139. * Display the post content.
  140. *
  141. * @since 0.71
  142. *
  143. * @param string $more_link_text Optional. Content for when there is more text.
  144. * @param string $stripteaser Optional. Teaser content before the more text.
  145. */
  146. function the_content($more_link_text = null, $stripteaser = 0) {
  147. $content = get_the_content($more_link_text, $stripteaser);
  148. $content = apply_filters('the_content', $content);
  149. $content = str_replace(']]>', ']]&gt;', $content);
  150. echo $content;
  151. }
  152. /**
  153. * Retrieve the post content.
  154. *
  155. * @since 0.71
  156. *
  157. * @param string $more_link_text Optional. Content for when there is more text.
  158. * @param string $stripteaser Optional. Teaser content before the more text.
  159. * @return string
  160. */
  161. function get_the_content($more_link_text = null, $stripteaser = 0) {
  162. global $id, $post, $more, $page, $pages, $multipage, $preview;
  163. if ( null === $more_link_text )
  164. $more_link_text = __( '(more...)' );
  165. $output = '';
  166. $hasTeaser = false;
  167. // If post password required and it doesn't match the cookie.
  168. if ( post_password_required($post) ) {
  169. $output = get_the_password_form();
  170. return $output;
  171. }
  172. if ( $page > count($pages) ) // if the requested page doesn't exist
  173. $page = count($pages); // give them the highest numbered page that DOES exist
  174. $content = $pages[$page-1];
  175. if ( preg_match('/<!--more(.*?)?-->/', $content, $matches) ) {
  176. $content = explode($matches[0], $content, 2);
  177. if ( !empty($matches[1]) && !empty($more_link_text) )
  178. $more_link_text = strip_tags(wp_kses_no_null(trim($matches[1])));
  179. $hasTeaser = true;
  180. } else {
  181. $content = array($content);
  182. }
  183. if ( (false !== strpos($post->post_content, '<!--noteaser-->') && ((!$multipage) || ($page==1))) )
  184. $stripteaser = 1;
  185. $teaser = $content[0];
  186. if ( ($more) && ($stripteaser) && ($hasTeaser) )
  187. $teaser = '';
  188. $output .= $teaser;
  189. if ( count($content) > 1 ) {
  190. if ( $more ) {
  191. $output .= '<span id="more-' . $id . '"></span>' . $content[1];
  192. } else {
  193. if ( ! empty($more_link_text) )
  194. $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-$id\" class=\"more-link\">$more_link_text</a>", $more_link_text );
  195. $output = force_balance_tags($output);
  196. }
  197. }
  198. if ( $preview ) // preview fix for javascript bug with foreign languages
  199. $output = preg_replace_callback('/\%u([0-9A-F]{4})/', create_function('$match', 'return "&#" . base_convert($match[1], 16, 10) . ";";'), $output);
  200. return $output;
  201. }
  202. /**
  203. * Display the post excerpt.
  204. *
  205. * @since 0.71
  206. * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
  207. */
  208. function the_excerpt() {
  209. echo apply_filters('the_excerpt', get_the_excerpt());
  210. }
  211. /**
  212. * Retrieve the post excerpt.
  213. *
  214. * @since 0.71
  215. *
  216. * @param mixed $deprecated Not used.
  217. * @return string
  218. */
  219. function get_the_excerpt( $deprecated = '' ) {
  220. if ( !empty( $deprecated ) )
  221. _deprecated_argument( __FUNCTION__, '2.3' );
  222. global $post;
  223. $output = $post->post_excerpt;
  224. if ( post_password_required($post) ) {
  225. $output = __('There is no excerpt because this is a protected post.');
  226. return $output;
  227. }
  228. return apply_filters('get_the_excerpt', $output);
  229. }
  230. /**
  231. * Whether post has excerpt.
  232. *
  233. * @since 2.3.0
  234. *
  235. * @param int $id Optional. Post ID.
  236. * @return bool
  237. */
  238. function has_excerpt( $id = 0 ) {
  239. $post = &get_post( $id );
  240. return ( !empty( $post->post_excerpt ) );
  241. }
  242. /**
  243. * Display the classes for the post div.
  244. *
  245. * @since 2.7.0
  246. *
  247. * @param string|array $class One or more classes to add to the class list.
  248. * @param int $post_id An optional post ID.
  249. */
  250. function post_class( $class = '', $post_id = null ) {
  251. // Separates classes with a single space, collates classes for post DIV
  252. echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
  253. }
  254. /**
  255. * Retrieve the classes for the post div as an array.
  256. *
  257. * The class names are add are many. If the post is a sticky, then the 'sticky'
  258. * class name. The class 'hentry' is always added to each post. For each
  259. * category, the class will be added with 'category-' with category slug is
  260. * added. The tags are the same way as the categories with 'tag-' before the tag
  261. * slug. All classes are passed through the filter, 'post_class' with the list
  262. * of classes, followed by $class parameter value, with the post ID as the last
  263. * parameter.
  264. *
  265. * @since 2.7.0
  266. *
  267. * @param string|array $class One or more classes to add to the class list.
  268. * @param int $post_id An optional post ID.
  269. * @return array Array of classes.
  270. */
  271. function get_post_class( $class = '', $post_id = null ) {
  272. $post = get_post($post_id);
  273. $classes = array();
  274. if ( empty($post) )
  275. return $classes;
  276. $classes[] = 'post-' . $post->ID;
  277. $classes[] = $post->post_type;
  278. $classes[] = 'type-' . $post->post_type;
  279. // sticky for Sticky Posts
  280. if ( is_sticky($post->ID) && is_home())
  281. $classes[] = 'sticky';
  282. // hentry for hAtom compliace
  283. $classes[] = 'hentry';
  284. // Categories
  285. foreach ( (array) get_the_category($post->ID) as $cat ) {
  286. if ( empty($cat->slug ) )
  287. continue;
  288. $classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->cat_ID);
  289. }
  290. // Tags
  291. foreach ( (array) get_the_tags($post->ID) as $tag ) {
  292. if ( empty($tag->slug ) )
  293. continue;
  294. $classes[] = 'tag-' . sanitize_html_class($tag->slug, $tag->term_id);
  295. }
  296. if ( !empty($class) ) {
  297. if ( !is_array( $class ) )
  298. $class = preg_split('#\s+#', $class);
  299. $classes = array_merge($classes, $class);
  300. }
  301. $classes = array_map('esc_attr', $classes);
  302. return apply_filters('post_class', $classes, $class, $post->ID);
  303. }
  304. /**
  305. * Display the classes for the body element.
  306. *
  307. * @since 2.8.0
  308. *
  309. * @param string|array $class One or more classes to add to the class list.
  310. */
  311. function body_class( $class = '' ) {
  312. // Separates classes with a single space, collates classes for body element
  313. echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
  314. }
  315. /**
  316. * Retrieve the classes for the body element as an array.
  317. *
  318. * @since 2.8.0
  319. *
  320. * @param string|array $class One or more classes to add to the class list.
  321. * @return array Array of classes.
  322. */
  323. function get_body_class( $class = '' ) {
  324. global $wp_query, $wpdb;
  325. $classes = array();
  326. if ( is_rtl() )
  327. $classes[] = 'rtl';
  328. if ( is_front_page() )
  329. $classes[] = 'home';
  330. if ( is_home() )
  331. $classes[] = 'blog';
  332. if ( is_archive() )
  333. $classes[] = 'archive';
  334. if ( is_date() )
  335. $classes[] = 'date';
  336. if ( is_search() )
  337. $classes[] = 'search';
  338. if ( is_paged() )
  339. $classes[] = 'paged';
  340. if ( is_attachment() )
  341. $classes[] = 'attachment';
  342. if ( is_404() )
  343. $classes[] = 'error404';
  344. if ( is_single() ) {
  345. $post_id = $wp_query->get_queried_object_id();
  346. $post = $wp_query->get_queried_object();
  347. $classes[] = 'single';
  348. $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id);
  349. $classes[] = 'postid-' . $post_id;
  350. if ( is_attachment() ) {
  351. $mime_type = get_post_mime_type($post_id);
  352. $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
  353. $classes[] = 'attachmentid-' . $post_id;
  354. $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
  355. }
  356. } elseif ( is_archive() ) {
  357. if ( is_author() ) {
  358. $author = $wp_query->get_queried_object();
  359. $classes[] = 'author';
  360. $classes[] = 'author-' . sanitize_html_class( $author->user_nicename , $author->ID );
  361. } elseif ( is_category() ) {
  362. $cat = $wp_query->get_queried_object();
  363. $classes[] = 'category';
  364. $classes[] = 'category-' . sanitize_html_class( $cat->slug, $cat->cat_ID );
  365. } elseif ( is_tag() ) {
  366. $tags = $wp_query->get_queried_object();
  367. $classes[] = 'tag';
  368. $classes[] = 'tag-' . sanitize_html_class( $tags->slug, $tags->term_id );
  369. }
  370. } elseif ( is_page() ) {
  371. $classes[] = 'page';
  372. $page_id = $wp_query->get_queried_object_id();
  373. $post = get_page($page_id);
  374. $classes[] = 'page-id-' . $page_id;
  375. if ( $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status = 'publish' LIMIT 1", $page_id) ) )
  376. $classes[] = 'page-parent';
  377. if ( $post->post_parent ) {
  378. $classes[] = 'page-child';
  379. $classes[] = 'parent-pageid-' . $post->post_parent;
  380. }
  381. if ( is_page_template() ) {
  382. $classes[] = 'page-template';
  383. $classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', get_post_meta( $page_id, '_wp_page_template', true ) ), '' );
  384. }
  385. } elseif ( is_search() ) {
  386. if ( !empty( $wp_query->posts ) )
  387. $classes[] = 'search-results';
  388. else
  389. $classes[] = 'search-no-results';
  390. }
  391. if ( is_user_logged_in() )
  392. $classes[] = 'logged-in';
  393. $page = $wp_query->get( 'page' );
  394. if ( !$page || $page < 2)
  395. $page = $wp_query->get( 'paged' );
  396. if ( $page && $page > 1 ) {
  397. $classes[] = 'paged-' . $page;
  398. if ( is_single() )
  399. $classes[] = 'single-paged-' . $page;
  400. elseif ( is_page() )
  401. $classes[] = 'page-paged-' . $page;
  402. elseif ( is_category() )
  403. $classes[] = 'category-paged-' . $page;
  404. elseif ( is_tag() )
  405. $classes[] = 'tag-paged-' . $page;
  406. elseif ( is_date() )
  407. $classes[] = 'date-paged-' . $page;
  408. elseif ( is_author() )
  409. $classes[] = 'author-paged-' . $page;
  410. elseif ( is_search() )
  411. $classes[] = 'search-paged-' . $page;
  412. }
  413. if ( !empty( $class ) ) {
  414. if ( !is_array( $class ) )
  415. $class = preg_split( '#\s+#', $class );
  416. $classes = array_merge( $classes, $class );
  417. }
  418. $classes = array_map( 'esc_attr', $classes );
  419. return apply_filters( 'body_class', $classes, $class );
  420. }
  421. /**
  422. * Whether post requires password and correct password has been provided.
  423. *
  424. * @since 2.7.0
  425. *
  426. * @param int|object $post An optional post. Global $post used if not provided.
  427. * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
  428. */
  429. function post_password_required( $post = null ) {
  430. $post = get_post($post);
  431. if ( empty($post->post_password) )
  432. return false;
  433. if ( !isset($_COOKIE['wp-postpass_' . COOKIEHASH]) )
  434. return true;
  435. if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password )
  436. return true;
  437. return false;
  438. }
  439. /**
  440. * Display "sticky" CSS class, if a post is sticky.
  441. *
  442. * @since 2.7.0
  443. *
  444. * @param int $post_id An optional post ID.
  445. */
  446. function sticky_class( $post_id = null ) {
  447. if ( !is_sticky($post_id) )
  448. return;
  449. echo " sticky";
  450. }
  451. /**
  452. * Page Template Functions for usage in Themes
  453. *
  454. * @package WordPress
  455. * @subpackage Template
  456. */
  457. /**
  458. * The formatted output of a list of pages.
  459. *
  460. * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
  461. * Quicktag one or more times). This tag must be within The Loop.
  462. *
  463. * The defaults for overwriting are:
  464. * 'next_or_number' - Default is 'number' (string). Indicates whether page
  465. * numbers should be used. Valid values are number and next.
  466. * 'nextpagelink' - Default is 'Next Page' (string). Text for link to next page.
  467. * of the bookmark.
  468. * 'previouspagelink' - Default is 'Previous Page' (string). Text for link to
  469. * previous page, if available.
  470. * 'pagelink' - Default is '%' (String).Format string for page numbers. The % in
  471. * the parameter string will be replaced with the page number, so Page %
  472. * generates "Page 1", "Page 2", etc. Defaults to %, just the page number.
  473. * 'before' - Default is '<p> Pages:' (string). The html or text to prepend to
  474. * each bookmarks.
  475. * 'after' - Default is '</p>' (string). The html or text to append to each
  476. * bookmarks.
  477. * 'link_before' - Default is '' (string). The html or text to prepend to each
  478. * Pages link inside the <a> tag.
  479. * 'link_after' - Default is '' (string). The html or text to append to each
  480. * Pages link inside the <a> tag.
  481. *
  482. * @since 1.2.0
  483. * @access private
  484. *
  485. * @param string|array $args Optional. Overwrite the defaults.
  486. * @return string Formatted output in HTML.
  487. */
  488. function wp_link_pages($args = '') {
  489. $defaults = array(
  490. 'before' => '<p>' . __('Pages:'), 'after' => '</p>',
  491. 'link_before' => '', 'link_after' => '',
  492. 'next_or_number' => 'number', 'nextpagelink' => __('Next page'),
  493. 'previouspagelink' => __('Previous page'), 'pagelink' => '%',
  494. 'echo' => 1
  495. );
  496. $r = wp_parse_args( $args, $defaults );
  497. $r = apply_filters( 'wp_link_pages_args', $r );
  498. extract( $r, EXTR_SKIP );
  499. global $post, $page, $numpages, $multipage, $more, $pagenow;
  500. $output = '';
  501. if ( $multipage ) {
  502. if ( 'number' == $next_or_number ) {
  503. $output .= $before;
  504. for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) {
  505. $j = str_replace('%',$i,$pagelink);
  506. $output .= ' ';
  507. if ( ($i != $page) || ((!$more) && ($page==1)) ) {
  508. if ( 1 == $i ) {
  509. $output .= '<a href="' . get_permalink() . '">';
  510. } else {
  511. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  512. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  513. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  514. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  515. else
  516. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  517. }
  518. }
  519. $output .= $link_before;
  520. $output .= $j;
  521. $output .= $link_after;
  522. if ( ($i != $page) || ((!$more) && ($page==1)) )
  523. $output .= '</a>';
  524. }
  525. $output .= $after;
  526. } else {
  527. if ( $more ) {
  528. $output .= $before;
  529. $i = $page - 1;
  530. if ( $i && $more ) {
  531. if ( 1 == $i ) {
  532. $output .= '<a href="' . get_permalink() . '">';
  533. } else {
  534. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  535. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  536. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  537. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  538. else
  539. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  540. }
  541. $output .= $link_before. $previouspagelink . $link_after . '</a>';
  542. }
  543. $i = $page + 1;
  544. if ( $i <= $numpages && $more ) {
  545. if ( 1 == $i ) {
  546. $output .= '<a href="' . get_permalink() . '">';
  547. } else {
  548. if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
  549. $output .= '<a href="' . add_query_arg('page', $i, get_permalink()) . '">';
  550. elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
  551. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit('page/' . $i, 'single_paged'). '">';
  552. else
  553. $output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
  554. }
  555. $output .= $link_before. $nextpagelink . $link_after . '</a>';
  556. }
  557. $output .= $after;
  558. }
  559. }
  560. }
  561. if ( $echo )
  562. echo $output;
  563. return $output;
  564. }
  565. //
  566. // Post-meta: Custom per-post fields.
  567. //
  568. /**
  569. * Retrieve post custom meta data field.
  570. *
  571. * @since 1.5.0
  572. *
  573. * @param string $key Meta data key name.
  574. * @return bool|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
  575. */
  576. function post_custom( $key = '' ) {
  577. $custom = get_post_custom();
  578. if ( !isset( $custom[$key] ) )
  579. return false;
  580. elseif ( 1 == count($custom[$key]) )
  581. return $custom[$key][0];
  582. else
  583. return $custom[$key];
  584. }
  585. /**
  586. * Display list of post custom fields.
  587. *
  588. * @internal This will probably change at some point...
  589. * @since 1.2.0
  590. * @uses apply_filters() Calls 'the_meta_key' on list item HTML content, with key and value as separate parameters.
  591. */
  592. function the_meta() {
  593. if ( $keys = get_post_custom_keys() ) {
  594. echo "<ul class='post-meta'>\n";
  595. foreach ( (array) $keys as $key ) {
  596. $keyt = trim($key);
  597. if ( '_' == $keyt{0} )
  598. continue;
  599. $values = array_map('trim', get_post_custom_values($key));
  600. $value = implode($values,', ');
  601. echo apply_filters('the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value);
  602. }
  603. echo "</ul>\n";
  604. }
  605. }
  606. //
  607. // Pages
  608. //
  609. /**
  610. * Retrieve or display list of pages as a dropdown (select list).
  611. *
  612. * @since 2.1.0
  613. *
  614. * @param array|string $args Optional. Override default arguments.
  615. * @return string HTML content, if not displaying.
  616. */
  617. function wp_dropdown_pages($args = '') {
  618. $defaults = array(
  619. 'depth' => 0, 'child_of' => 0,
  620. 'selected' => 0, 'echo' => 1,
  621. 'name' => 'page_id', 'id' => '',
  622. 'show_option_none' => '', 'show_option_no_change' => '',
  623. 'option_none_value' => ''
  624. );
  625. $r = wp_parse_args( $args, $defaults );
  626. extract( $r, EXTR_SKIP );
  627. $pages = get_pages($r);
  628. $output = '';
  629. $name = esc_attr($name);
  630. // Back-compat with old system where both id and name were based on $name argument
  631. if ( empty($id) )
  632. $id = $name;
  633. if ( ! empty($pages) ) {
  634. $output = "<select name=\"$name\" id=\"$id\">\n";
  635. if ( $show_option_no_change )
  636. $output .= "\t<option value=\"-1\">$show_option_no_change</option>";
  637. if ( $show_option_none )
  638. $output .= "\t<option value=\"" . esc_attr($option_none_value) . "\">$show_option_none</option>\n";
  639. $output .= walk_page_dropdown_tree($pages, $depth, $r);
  640. $output .= "</select>\n";
  641. }
  642. $output = apply_filters('wp_dropdown_pages', $output);
  643. if ( $echo )
  644. echo $output;
  645. return $output;
  646. }
  647. /**
  648. * Retrieve or display list of pages in list (li) format.
  649. *
  650. * @since 1.5.0
  651. *
  652. * @param array|string $args Optional. Override default arguments.
  653. * @return string HTML content, if not displaying.
  654. */
  655. function wp_list_pages($args = '') {
  656. $defaults = array(
  657. 'depth' => 0, 'show_date' => '',
  658. 'date_format' => get_option('date_format'),
  659. 'child_of' => 0, 'exclude' => '',
  660. 'title_li' => __('Pages'), 'echo' => 1,
  661. 'authors' => '', 'sort_column' => 'menu_order, post_title',
  662. 'link_before' => '', 'link_after' => '', 'walker' => '',
  663. );
  664. $r = wp_parse_args( $args, $defaults );
  665. extract( $r, EXTR_SKIP );
  666. $output = '';
  667. $current_page = 0;
  668. // sanitize, mostly to keep spaces out
  669. $r['exclude'] = preg_replace('/[^0-9,]/', '', $r['exclude']);
  670. // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
  671. $exclude_array = ( $r['exclude'] ) ? explode(',', $r['exclude']) : array();
  672. $r['exclude'] = implode( ',', apply_filters('wp_list_pages_excludes', $exclude_array) );
  673. // Query pages.
  674. $r['hierarchical'] = 0;
  675. $pages = get_pages($r);
  676. if ( !empty($pages) ) {
  677. if ( $r['title_li'] )
  678. $output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
  679. global $wp_query;
  680. if ( is_page() || is_attachment() || $wp_query->is_posts_page )
  681. $current_page = $wp_query->get_queried_object_id();
  682. $output .= walk_page_tree($pages, $r['depth'], $current_page, $r);
  683. if ( $r['title_li'] )
  684. $output .= '</ul></li>';
  685. }
  686. $output = apply_filters('wp_list_pages', $output, $r);
  687. if ( $r['echo'] )
  688. echo $output;
  689. else
  690. return $output;
  691. }
  692. /**
  693. * Display or retrieve list of pages with optional home link.
  694. *
  695. * The arguments are listed below and part of the arguments are for {@link
  696. * wp_list_pages()} function. Check that function for more info on those
  697. * arguments.
  698. *
  699. * <ul>
  700. * <li><strong>sort_column</strong> - How to sort the list of pages. Defaults
  701. * to page title. Use column for posts table.</li>
  702. * <li><strong>menu_class</strong> - Class to use for the div ID which contains
  703. * the page list. Defaults to 'menu'.</li>
  704. * <li><strong>echo</strong> - Whether to echo list or return it. Defaults to
  705. * echo.</li>
  706. * <li><strong>link_before</strong> - Text before show_home argument text.</li>
  707. * <li><strong>link_after</strong> - Text after show_home argument text.</li>
  708. * <li><strong>show_home</strong> - If you set this argument, then it will
  709. * display the link to the home page. The show_home argument really just needs
  710. * to be set to the value of the text of the link.</li>
  711. * </ul>
  712. *
  713. * @since 2.7.0
  714. *
  715. * @param array|string $args
  716. */
  717. function wp_page_menu( $args = array() ) {
  718. $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
  719. $args = wp_parse_args( $args, $defaults );
  720. $args = apply_filters( 'wp_page_menu_args', $args );
  721. $menu = '';
  722. $list_args = $args;
  723. // Show Home in the menu
  724. if ( ! empty($args['show_home']) ) {
  725. if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
  726. $text = __('Home');
  727. else
  728. $text = $args['show_home'];
  729. $class = '';
  730. if ( is_front_page() && !is_paged() )
  731. $class = 'class="current_page_item"';
  732. $menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '" title="' . esc_attr($text) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
  733. // If the front page is a page, add it to the exclude list
  734. if (get_option('show_on_front') == 'page') {
  735. if ( !empty( $list_args['exclude'] ) ) {
  736. $list_args['exclude'] .= ',';
  737. } else {
  738. $list_args['exclude'] = '';
  739. }
  740. $list_args['exclude'] .= get_option('page_on_front');
  741. }
  742. }
  743. $list_args['echo'] = false;
  744. $list_args['title_li'] = '';
  745. $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
  746. if ( $menu )
  747. $menu = '<ul>' . $menu . '</ul>';
  748. $menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
  749. $menu = apply_filters( 'wp_page_menu', $menu, $args );
  750. if ( $args['echo'] )
  751. echo $menu;
  752. else
  753. return $menu;
  754. }
  755. //
  756. // Page helpers
  757. //
  758. /**
  759. * Retrieve HTML list content for page list.
  760. *
  761. * @uses Walker_Page to create HTML list content.
  762. * @since 2.1.0
  763. * @see Walker_Page::walk() for parameters and return description.
  764. */
  765. function walk_page_tree($pages, $depth, $current_page, $r) {
  766. if ( empty($r['walker']) )
  767. $walker = new Walker_Page;
  768. else
  769. $walker = $r['walker'];
  770. $args = array($pages, $depth, $r, $current_page);
  771. return call_user_func_array(array(&$walker, 'walk'), $args);
  772. }
  773. /**
  774. * Retrieve HTML dropdown (select) content for page list.
  775. *
  776. * @uses Walker_PageDropdown to create HTML dropdown content.
  777. * @since 2.1.0
  778. * @see Walker_PageDropdown::walk() for parameters and return description.
  779. */
  780. function walk_page_dropdown_tree() {
  781. $args = func_get_args();
  782. if ( empty($args[2]['walker']) ) // the user's options are the third parameter
  783. $walker = new Walker_PageDropdown;
  784. else
  785. $walker = $args[2]['walker'];
  786. return call_user_func_array(array(&$walker, 'walk'), $args);
  787. }
  788. //
  789. // Attachments
  790. //
  791. /**
  792. * Display an attachment page link using an image or icon.
  793. *
  794. * @since 2.0.0
  795. *
  796. * @param int $id Optional. Post ID.
  797. * @param bool $fullsize Optional, default is false. Whether to use full size.
  798. * @param bool $deprecated Deprecated. Not used.
  799. * @param bool $permalink Optional, default is false. Whether to include permalink.
  800. */
  801. function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
  802. if ( !empty( $deprecated ) )
  803. _deprecated_argument( __FUNCTION__, '2.5' );
  804. if ( $fullsize )
  805. echo wp_get_attachment_link($id, 'full', $permalink);
  806. else
  807. echo wp_get_attachment_link($id, 'thumbnail', $permalink);
  808. }
  809. /**
  810. * Retrieve an attachment page link using an image or icon, if possible.
  811. *
  812. * @since 2.5.0
  813. * @uses apply_filters() Calls 'wp_get_attachment_link' filter on HTML content with same parameters as function.
  814. *
  815. * @param int $id Optional. Post ID.
  816. * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string.
  817. * @param bool $permalink Optional, default is false. Whether to add permalink to image.
  818. * @param bool $icon Optional, default is false. Whether to include icon.
  819. * @param string $text Optional, default is false. If string, then will be link text.
  820. * @return string HTML content.
  821. */
  822. function wp_get_attachment_link($id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false) {
  823. $id = intval($id);
  824. $_post = & get_post( $id );
  825. if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
  826. return __('Missing Attachment');
  827. if ( $permalink )
  828. $url = get_attachment_link($_post->ID);
  829. $post_title = esc_attr($_post->post_title);
  830. if ( $text ) {
  831. $link_text = esc_attr($text);
  832. } elseif ( ( is_int($size) && $size != 0 ) or ( is_string($size) && $size != 'none' ) or $size != false ) {
  833. $link_text = wp_get_attachment_image($id, $size, $icon);
  834. } else {
  835. $link_text = '';
  836. }
  837. if( trim($link_text) == '' )
  838. $link_text = $_post->post_title;
  839. return apply_filters( 'wp_get_attachment_link', "<a href='$url' title='$post_title'>$link_text</a>", $id, $size, $permalink, $icon, $text );
  840. }
  841. /**
  842. * Wrap attachment in <<p>> element before content.
  843. *
  844. * @since 2.0.0
  845. * @uses apply_filters() Calls 'prepend_attachment' hook on HTML content.
  846. *
  847. * @param string $content
  848. * @return string
  849. */
  850. function prepend_attachment($content) {
  851. global $post;
  852. if ( empty($post->post_type) || $post->post_type != 'attachment' )
  853. return $content;
  854. $p = '<p class="attachment">';
  855. // show the medium sized image representation of the attachment if available, and link to the raw file
  856. $p .= wp_get_attachment_link(0, 'medium', false);
  857. $p .= '</p>';
  858. $p = apply_filters('prepend_attachment', $p);
  859. return "$p\n$content";
  860. }
  861. //
  862. // Misc
  863. //
  864. /**
  865. * Retrieve protected post password form content.
  866. *
  867. * @since 1.0.0
  868. * @uses apply_filters() Calls 'the_password_form' filter on output.
  869. *
  870. * @return string HTML content for password form for password protected post.
  871. */
  872. function get_the_password_form() {
  873. global $post;
  874. $label = 'pwbox-'.(empty($post->ID) ? rand() : $post->ID);
  875. $output = '<form action="' . get_option('siteurl') . '/wp-pass.php" method="post">
  876. <p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
  877. <p><label for="' . $label . '">' . __("Password:") . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr__("Submit") . '" /></p>
  878. </form>
  879. ';
  880. return apply_filters('the_password_form', $output);
  881. }
  882. /**
  883. * Whether currently in a page template.
  884. *
  885. * This template tag allows you to determine if you are in a page template.
  886. * You can optionally provide a template name and then the check will be
  887. * specific to that template.
  888. *
  889. * @since 2.5.0
  890. * @uses $wp_query
  891. *
  892. * @param string $template The specific template name if specific matching is required.
  893. * @return bool False on failure, true if success.
  894. */
  895. function is_page_template($template = '') {
  896. if (!is_page()) {
  897. return false;
  898. }
  899. global $wp_query;
  900. $page = $wp_query->get_queried_object();
  901. $custom_fields = get_post_custom_values('_wp_page_template',$page->ID);
  902. $page_template = $custom_fields[0];
  903. // We have no argument passed so just see if a page_template has been specified
  904. if ( empty( $template ) ) {
  905. if (!empty( $page_template ) ) {
  906. return true;
  907. }
  908. } elseif ( $template == $page_template) {
  909. return true;
  910. }
  911. return false;
  912. }
  913. /**
  914. * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  915. *
  916. * @package WordPress
  917. * @subpackage Post_Revisions
  918. * @since 2.6.0
  919. *
  920. * @uses date_i18n()
  921. *
  922. * @param int|object $revision Revision ID or revision object.
  923. * @param bool $link Optional, default is true. Link to revisions's page?
  924. * @return string i18n formatted datetimestamp or localized 'Current Revision'.
  925. */
  926. function wp_post_revision_title( $revision, $link = true ) {
  927. if ( !$revision = get_post( $revision ) )
  928. return $revision;
  929. if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  930. return false;
  931. /* translators: revision date format, see http://php.net/date */
  932. $datef = _x( 'j F, Y @ G:i', 'revision date format');
  933. /* translators: 1: date */
  934. $autosavef = __( '%1$s [Autosave]' );
  935. /* translators: 1: date */
  936. $currentf = __( '%1$s [Current Revision]' );
  937. $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  938. if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  939. $date = "<a href='$link'>$date</a>";
  940. if ( !wp_is_post_revision( $revision ) )
  941. $date = sprintf( $currentf, $date );
  942. elseif ( wp_is_post_autosave( $revision ) )
  943. $date = sprintf( $autosavef, $date );
  944. return $date;
  945. }
  946. /**
  947. * Display list of a post's revisions.
  948. *
  949. * Can output either a UL with edit links or a TABLE with diff interface, and
  950. * restore action links.
  951. *
  952. * Second argument controls parameters:
  953. * (bool) parent : include the parent (the "Current Revision") in the list.
  954. * (string) format : 'list' or 'form-table'. 'list' outputs UL, 'form-table'
  955. * outputs TABLE with UI.
  956. * (int) right : what revision is currently being viewed - used in
  957. * form-table format.
  958. * (int) left : what revision is currently being diffed against right -
  959. * used in form-table format.
  960. *
  961. * @package WordPress
  962. * @subpackage Post_Revisions
  963. * @since 2.6.0
  964. *
  965. * @uses wp_get_post_revisions()
  966. * @uses wp_post_revision_title()
  967. * @uses get_edit_post_link()
  968. * @uses get_the_author_meta()
  969. *
  970. * @todo split into two functions (list, form-table) ?
  971. *
  972. * @param int|object $post_id Post ID or post object.
  973. * @param string|array $args See description {@link wp_parse_args()}.
  974. * @return null
  975. */
  976. function wp_list_post_revisions( $post_id = 0, $args = null ) {
  977. if ( !$post = get_post( $post_id ) )
  978. return;
  979. $defaults = array( 'parent' => false, 'right' => false, 'left' => false, 'format' => 'list', 'type' => 'all' );
  980. extract( wp_parse_args( $args, $defaults ), EXTR_SKIP );
  981. switch ( $type ) {
  982. case 'autosave' :
  983. if ( !$autosave = wp_get_post_autosave( $post->ID ) )
  984. return;
  985. $revisions = array( $autosave );
  986. break;
  987. case 'revision' : // just revisions - remove autosave later
  988. case 'all' :
  989. default :
  990. if ( !$revisions = wp_get_post_revisions( $post->ID ) )
  991. return;
  992. break;
  993. }
  994. /* translators: post revision: 1: when, 2: author name */
  995. $titlef = _x( '%1$s by %2$s', 'post revision' );
  996. if ( $parent )
  997. array_unshift( $revisions, $post );
  998. $rows = '';
  999. $class = false;
  1000. $can_edit_post = current_user_can( 'edit_post', $post->ID );
  1001. foreach ( $revisions as $revision ) {
  1002. if ( !current_user_can( 'read_post', $revision->ID ) )
  1003. continue;
  1004. if ( 'revision' === $type && wp_is_post_autosave( $revision ) )
  1005. continue;
  1006. $date = wp_post_revision_title( $revision );
  1007. $name = get_the_author_meta( 'display_name', $revision->post_author );
  1008. if ( 'form-table' == $format ) {
  1009. if ( $left )
  1010. $left_checked = $left == $revision->ID ? ' checked="checked"' : '';
  1011. else
  1012. $left_checked = $right_checked ? ' checked="checked"' : ''; // [sic] (the next one)
  1013. $right_checked = $right == $revision->ID ? ' checked="checked"' : '';
  1014. $class = $class ? '' : " class='alternate'";
  1015. if ( $post->ID != $revision->ID && $can_edit_post )
  1016. $actions = '<a href="' . wp_nonce_url( add_query_arg( array( 'revision' => $revision->ID, 'diff' => false, 'action' => 'restore' ) ), "restore-post_$post->ID|$revision->ID" ) . '">' . __( 'Restore' ) . '</a>';
  1017. else
  1018. $actions = '';
  1019. $rows .= "<tr$class>\n";
  1020. $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='left' value='$revision->ID'$left_checked />\n";
  1021. $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='right' value='$revision->ID'$right_checked /></th>\n";
  1022. $rows .= "\t<td>$date</td>\n";
  1023. $rows .= "\t<td>$name</td>\n";
  1024. $rows .= "\t<td class='action-links'>$actions</td>\n";
  1025. $rows .= "</tr>\n";
  1026. } else {
  1027. $title = sprintf( $titlef, $date, $name );
  1028. $rows .= "\t<li>$title</li>\n";
  1029. }
  1030. }
  1031. if ( 'form-table' == $format ) : ?>
  1032. <form action="revision.php" method="get">
  1033. <div class="tablenav">
  1034. <div class="alignleft">
  1035. <input type="submit" class="button-secondary" value="<?php esc_attr_e( 'Compare Revisions' ); ?>" />
  1036. <input type="hidden" name="action" value="diff" />
  1037. <input type="hidden" name="post_type" value="<?php echo esc_attr($post->post_type); ?>" />
  1038. </div>
  1039. </div>
  1040. <br class="clear" />
  1041. <table class="widefat post-revisions" cellspacing="0" id="post-revisions">
  1042. <col />
  1043. <col />
  1044. <col style="width: 33%" />
  1045. <col style="width: 33%" />
  1046. <col style="width: 33%" />
  1047. <thead>
  1048. <tr>
  1049. <th scope="col"><?php _e( 'Old' ); ?></th>
  1050. <th scope="col"><?php _e( 'New' ); ?></th>
  1051. <th scope="col"><?php _e( 'Date Created' ); ?></th>
  1052. <th scope="col"><?php _e( 'Author' ); ?></th>
  1053. <th scope="col" class="action-links"><?php _e( 'Actions' ); ?></th>
  1054. </tr>
  1055. </thead>
  1056. <tbody>
  1057. <?php echo $rows; ?>
  1058. </tbody>
  1059. </table>
  1060. </form>
  1061. <?php
  1062. else :
  1063. echo "<ul class='post-revisions'>\n";
  1064. echo $rows;
  1065. echo "</ul>";
  1066. endif;
  1067. }