Если ваша тема активно использует механизм мета полей WordPress то это приведет к неизбежным потерям производительности т.к. каждый вызов get_post_meta или get_post_custom может генерировать лишний SQL к базе данных, если данных нет в кеш. Особенно заметно это будет при создании списка категории или главной страницы, когда эти функции вызываются в теле основного цикла.
Чтобы этого избежать можно подключить фильтр posts_results в фильтре мы получим результат последней выборки — массив постов, далее собираем все ID и формируем новый запрос в таблицу postmeta забираем там сразу все meta для всех постов и это будет намного быстрее чем каждый раз дергать выше упомянутые функции.
// этот фильтр добавляем в function.php function ads_addImgMeta($posts){ global $wpdb, $wp_query; if(is_admin() or is_page() ) return $posts; // сохраняем состояние объекта $wp_query и $wpdb if(( (), '5.0', '>=' )){ $wpdb_save = clone($wpdb); $wp_query_save = clone($wp_query); } else{ $wpdb_save = $wpdb; $wp_query_save = $wp_query; } $ar_post_id = (); foreach ($posts as $key => $post) { $ar_post_id[] = $post->ID; $ar_link[$post->ID] = & $posts[$key]; } $st_id = @("','", $ar_post_id); // складываем получаем общий список $st_id = ("','", $ar_post_id); $query = "SELECT * FROM $wpdb->postmeta WHERE post_id IN ('$st_id') "; $meta = $wpdb->get_results($query); if(!($meta))return $posts; // теперь цепляем meta дане к постам $uploads_dir = wp_upload_dir('baseurl'); foreach ($meta as $row) { $meta_value = maybe_unserialize($row->meta_value); $ar_link[$row->post_id]->meta[$row->meta_key] = $meta_value; } // востанавливаем состояние объектов ( $wpdb, $wp_query ); $wpdb = & $wpdb_save; $wp_query = & $wp_query_save; ( $wpdb_save, $wp_query_save ); return $posts; } add_filter('posts_results', 'ads_addImgMeta'); |
Вот так вот одним махом теперь все мета поля сидят у нас в $post. Используйте в теле основного цикла if ( have_posts() ) : while ( have_posts() ) : the_post(); доступ к вашим полям $post->meta[meta_key]
А вот если мы используем WordPress как CMS, часто возникает задача добавлять картинки к короткому анонсу поста, то есть когда html код тега img надо удалить или надо использовать цитату (http://codex.wordpress.org/Template_Tags/the_excerpt) совмесно с картинкой вот как здесь
В этом случае нужно потратится на еще один SQL и получить сразу все атачменты для сразу всех постов а затем для всех ID получить мета поля. Привожу код:
function AddImgMeta($posts){ // можно исключить категории в которых не надо поулучать meta if(is_admin() or is_category('307,3,5,4')) return $posts; global $wpdb, $wp_query; // сохраняем состояние объекта $wp_query и $wpdb if(( (), '5.0', '>=' )){ $wpdb_save = clone($wpdb); $wp_query_save = clone($wp_query); } else{ $wpdb_save = $wpdb; $wp_query_save = $wp_query; } $ar_post_id = (); foreach ($posts as $key => $post) { $ar_post_id[] = $post->ID; $ar_link[$post->ID] = & $posts[$key]; } $st_id = @("','", $ar_post_id); //сначала добываем атачменты $query = "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE $wpdb->posts.post_parent IN('$st_id') AND $wpdb->posts.post_parent AND $wpdb->posts.post_type = 'attachment'"; $files = $wpdb->get_results($query); // получаем список id атачментов $ar_file_id = (); foreach ($files as $key=>$file) { $ar_file_id[] = $file->ID; $ar_link[$file->ID] = & $files[$key]; } // складываем получаем общий список $ar_all_id = @($ar_post_id,$ar_file_id); $st_id = ("','", $ar_all_id); $query = "SELECT * FROM $wpdb->postmeta WHERE post_id IN ('$st_id') "; $meta = $wpdb->get_results($query); if(!($meta))return $posts; // теперь цепляем meta дане к постам $uploads_dir = wp_upload_dir('baseurl'); foreach ($meta as $row) { $meta_value = maybe_unserialize($row->meta_value); //'thumbnail' | 'medium' | if('_wp_attachment_metadata'==$row->meta_key AND ($meta_value) ){ $imgUrl = ($meta_value['file'], '/wp-content'); if(!$imgUrl){ $imgUrl = $uploads_dir['baseurl'].'/'. $meta_value['file']; } $dirname = ($imgUrl); $thumbUrl = $dirname.'/'.$meta_value['sizes']['thumbnail']['file']; $mediumUrl = $dirname.'/'.$meta_value['sizes']['medium']['file']; $ar_link[$row->post_id]->imgUrl = $imgUrl; $ar_link[$row->post_id]->thumbUrl = $thumbUrl; $ar_link[$row->post_id]->mediumUrl = $mediumUrl; } $ar_link[$row->post_id]->meta[$row->meta_key] = $meta_value; } // теперь цепляем атачменты к постам foreach ($files as $row) { $ar_link[$row->post_parent]->files[$row->menu_order] = $row; } // востанавливаем состояние объектов ( $wpdb, $wp_query ); $wpdb = & $wpdb_save; $wp_query = & $wp_query_save; ( $wpdb_save, $wp_query_save ); return $posts; } add_filter('posts_results', 'AddImgMeta'); |
Сначала получаем ID всех постов из массива $posts, делаем первый SELECT для всех постов получаем все атачменты (см. SQL оператор IN) затем получаем ID всех атачментов напомню, что атачменты это такие же посты только без текста и хранятся они в одной таблице. Складываем два массива $ar_all_id = @array_merge($ar_post_id,$ar_file_id); и делаем запрос теперь уже в таблицу postmeta получаем все мета поля.
Надо также сказать, что WP хранит дополнительную информацию о закачанных картинках в тех же самых мета полях глвное нас интересует поля с именем _wp_attachment_metadata здесь хранятся ссылки на две превьюшки маленькую и среднюю которые автоматически нарезаются WP при загрузке изображений.
Мы обработаем эти данные и создадим дополнительно 3 свойства imgUrl thumbUrl mediumUrl которые содержат соответственно полный url на кртинку, url на маленькую превьюшку и url на среднюю картинку.
Чтобы посмотреть, что где лежит распечатайте переменную $post в теле основного цикла
echo ‘<pre>’; print_r( $post ); echo ‘</pre>’;
Да ! самое главное не путайте где массив, а где свойство объекта а то получите фатальную ошибку.
Чтобы все разложить по полочкам приведу пример что же мы получим в переменной $post .
stdClass Object ( [ID] => 900 [post_author] => 2 [post_date] => 2009-03-23 16:06:03 [post_date_gmt] => 2009-03-23 13:06:03 [post_content] => Паркетная доска Barlinek это пол высочайшего класса, изготовленный из древесины, не подверженной процессам модификации. Отлично соединяет эстетические качества с легкостью монтажа и обновления. Паркетная доска Барлинек обеспечивает высокую термическую и акустическую изоляцию, имеет большое [post_title] => Продажа паркетной доски!!! [post_category] => 0 [post_excerpt] => [post_status] => publish [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => prodazha-parketnoj-doski [to_ping] => [pinged] => [post_modified] => 2009-03-23 16:06:03 [post_modified_gmt] => 2009-03-23 13:06:03 [post_content_filtered] => [post_parent] => 0 [guid] => http://wtb.od.ua/?p=900 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [meta] => ( [ads_location] => 0 [ads_url] => [ads_phone] => 096-358-94-21 / 093-050-35-43 [ads_email] => morabend_sin@.ru [ads_password] => qwewe [ads_basecat] => 6 [ads_files] => ( [0] => 899 ) ) [files] => ( [0] => stdClass Object ( [ID] => 899 [post_author] => 0 [post_date] => 2009-03-23 16:05:40 [post_date_gmt] => 2009-03-23 13:05:40 [post_content] => [post_title] => barlinek4.jpg [post_category] => 0 [post_excerpt] => [post_status] => inherit [comment_status] => open [ping_status] => closed [post_password] => [post_name] => barlinek4jpg [to_ping] => [pinged] => [post_modified] => 2009-03-23 16:05:40 [post_modified_gmt] => 2009-03-23 13:05:40 [post_content_filtered] => [post_parent] => 900 [guid] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4.jpg [menu_order] => 0 [post_type] => attachment [post_mime_type] => image/jpeg [comment_count] => 0 [meta] => ( [_wp_attached_file] => 2009/03/barlinek4.jpg [_wp_attachment_metadata] => ( [width] => 274 [height] => 480 [hwstring_small] => height='96' width='54' [] => 2009/03/barlinek4.jpg [sizes] => ( [thumbnail] => ( [] => barlinek4-150x150.jpg [width] => 150 [height] => 150 ) [medium] => ( [] => barlinek4-171x300.jpg [width] => 171 [height] => 300 ) ) [image_meta] => ( [aperture] => 0 [credit] => [camera] => [caption] => [created_timestamp] => 0 [copyright] => [focal_length] => 0 [iso] => 0 [shutter_speed] => 0 [title] => ) ) ) [imgUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4.jpg [thumbUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4-150x150.jpg [mediumUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4-171x300.jpg ) ) ) |
Вывести любое мета поле например ads_email
<?=$post->meta['ads_email']?> |
А теперь как вывести первую картинку в шаблоне.
<? if($post->files[0]):?> <a href="<?the_permalink()?>"><img src="<?=$post->files[0]->thumbUrl?>" title="<?=$post->files[0]->post_title?>" width="80px" /></a> <?endif;?> |
Здесь есть тонкий момент все атачменты — картинки или другие файлы zip или rar архивы будут сортироваться по времени и все они будут содержатся в массиве $files, поэтому чтобы все правильно отобразилось картинку надо загружать первой.
Ну а теперь выводим все картинки в виде превьюшек со сcылкой на основную картинку.
<div> <?foreach ($post->files as $key=>$value):?> <? if(($value->post_mime_type,'image/') === false ) continue;?> <a href="<?=$post->files[$key]->guid;?>"> <img class="alignleft" src="<?=$post->files[$key]->thumbUrl?>" /> </a> <?endforeach;?> </div> |
Цикл выведет все картинки, дополнительно реализованна проверка mime type у файла if(strstr($value->post_mime_type,’image/’) === false ) continue; в данном случае только изображения.
Напомню что все эти конструкции мы применяем внутри основного цикла вашего шаблона темы!
if ( have_posts() ) : while ( have_posts() ) : the_post();
Здравствуйте, не подскажете более подробно как этим пользоваться, у меня из картинки берутся из custom filds вот таким образом:
<a href=»"><img class=»preview» width=»133″ height=»100″ src=»ID, «preview», true); ?>» />
Как использовать Ваш код, заранее спасибо!
ну да все правильно на 2 запроса больше, очевидно ваша тема не настолько активно использует мета поля так что нет смысла внедрять этот код
а как вывести полный список городов расположения со ссылками, например в виджете?
Используйте текстовый виджет например
то есть вручную набирать ссылки?
Ну да типа того лично просто сделал отдельный файл и inclode вставил вот и все