Listare categorii cu thumbnail și descriere pe pagina principală
Am nevoie de o soluție cuprinzătoare pentru aceasta, așa că ofer aproape un sfert din reputația mea ca recompensă :)
Aș dori să am un plugin care creează o listă personalizată de categorii pe pagina mea principală. Pentru aceasta, aș dori ca ecranul "Editare Categorie" să fie îmbunătățit cu câteva funcții suplimentare, după cum urmează...
- Adaugă un handler "Încarcă/Șterge Imagine" în ecranul de Editare Categorie pentru o anumită categorie (aceasta permite utilizatorului final să încarce o imagine care va reprezenta categoria. Ideal, ar trebui să fie redimensionată automat la 125 de pixeli lățime de către plugin la încărcare.
- Adaugă un câmp de introducere "Titlu Categorie" în ecranul de Editare Categorie pentru o anumită categorie. Acesta este în plus față de câmpul "Nume" existent implicit.
- Adaugă o casetă de bifat intitulată "Afișează în lista de pe pagina principală" pentru a permite afișarea selectivă a fiecărei categorii în lista de pe pagina principală.
- Când pagina principală este vizualizată, pluginul adaugă the_content cu lista personalizată de categorii, inclusiv thumbnail-ul și titlul personalizat al fiecărei categorii.
Marcajul rezultat ar trebui să fie o listă neordonată fără cuibărire, astfel...
<ul class="custom-categories">
<li>
<span><a href="link-to-category-1"><img src="the-category-1-image" /></a></span>
<a href="link-to-category-1">Category 1 Title</a> Textul descrierii categoriei va fi aici
</li>
<li>
<span><a href="link-to-category-2"><img src="the-category-2-image" /></a></span>
<a href="link-to-category-2">Category 2 Title</a> Textul descrierii categoriei va fi aici
</li>
etc...
</ul>
Iată un fișier stub pe care l-am început...
add_filter( 'the_content', 'cb_category_listing' );
function cb_category_listing( $content )
{
if ( is_home() ) {
$cat_args['title_li'] = '';
$cat_args['exclude_tree'] = 1;
$cat_args['exclude'] = 1;
$myContent = wp_list_categories(apply_filters('widget_categories_args', $cat_args));
$content .= $myContent;
}
return $content;
}

Notă: Acest ghid este pentru versiuni mai vechi de WP < 3.9, înainte de introducerea noii funcționalități de încărcare media
Iată cum să adăugați câmpuri personalizate și să salvați valorile pe ecranul de editare a categoriei, precum și o metodă de a adăuga un câmp pentru încărcare de imagini.
Adăugarea de câmpuri pe ecranul de editare a categoriei
Pentru început, avem nevoie să afișăm niște cod pe ecranul de editare a categoriei.
add_action( 'edit_category_form_fields', 'my_category_custom_fields' );
add_action( 'edit_category', 'save_my_category_custom_fields' );
function my_category_custom_fields( $tag ) {
// aici va fi HTML-ul pentru câmpurile personalizate
// variabila $tag este un obiect termen de taxonomie cu proprietăți precum $tag->name, $tag->term_id etc.
// avem nevoie de valorile intrărilor existente, dacă există
$category_meta = get_option( 'category_meta' );
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="category-title"><?php _e("Titlu"); ?></label></th>
<td>
<input id="category-title" name="category_meta[<?php echo $tag->term_id ?>][title]" value="<?php if ( isset( $category_meta[ $tag->term_id ] ) ) esc_attr_e( $category_meta[ $tag->term_id ]['title'] ); ?>" />
<span class="description"><?php _e('Introduceți un titlu alternativ pentru această categorie.'); ?></span>
</td>
</tr>
<!-- repetați pentru alte câmpuri necesare -->
<?php
}
Cea mai simplă metodă de a stoca valorile personalizate este în tabelul de opțiuni (ar trebui să existe un tabel taxonomy-meta, dar nu este). Astfel, avem nevoie de o singură interogare pentru a obține metadatele pentru toate categoriile noastre. Dacă cineva are o idee mai bună pentru stocare, spuneți-ne!
function save_my_category_custom_fields() {
if ( isset( $_POST['category_meta'] ) && !update_option('category_meta', $_POST['category_meta']) )
add_option('category_meta', $_POST['category_meta']);
}
Pentru un checkbox, stocați pur și simplu true sau false, așadar veți folosi category_extras[$tag->term_id][show_on_home]
pentru atributul name și veți folosi valoarea stocată în $category_meta
pentru a determina dacă este bifat sau nu.
Este posibil să doriți să adăugați procesare sau validare suplimentară funcției de salvare - exemplul meu este doar rapid și simplist.
Câmpul pentru imagine
Acesta este un cod destul de complex, așa că nu îl voi explica pe larg aici, dar comentariile descriu scopul fiecărei funcții. Putem discuta în comentarii dacă doriți.
Următoarele funcții adaugă un link pe ecranul de editare a categoriei care deschide popup-ul WordPress pentru biblioteca media/încărcare imagini. Puteți încărca o imagine și apoi să o selectați. Veți avea la dispoziție ID-ul imaginii și URL-ul thumbnail-ului împreună cu celelalte metadate.
// adăugați dimensiunea imaginii de care aveți nevoie
add_image_size( 'category_thumb', 125, 125, true );
// configurați câmpul pentru imagine și metodele de manipulare
function setup_category_image_handling() {
// adăugați câmpul pentru imagine la celelalte
add_action( 'edit_category_form_fields', 'category_image' );
global $pagenow;
if ( is_admin() ) {
add_action( 'admin_init', 'fix_async_upload_image' );
if ( 'edit-tags.php' == $pagenow ) {
add_thickbox();
add_action('admin_print_footer_scripts', 'category_image_send_script', 1000);
} elseif ( 'media-upload.php' == $pagenow || 'async-upload.php' == $pagenow ) {
add_filter( 'media_send_to_editor', 'category_image_send_to_editor', 1, 8 );
add_filter( 'gettext', 'category_image_replace_text_in_thickbox', 1, 3 );
}
}
}
add_action( 'admin_init', 'setup_category_image_handling' );
// câmpul pentru imagine pe ecranul de editare a taxonomiei
function category_image( $tag ) {
// obțineți metadatele categoriei
$category_meta = get_option('category_meta');
?>
<tr class="form-field hide-if-no-js">
<th scope="row" valign="top"><label for="taxonomy-image"><?php _e("Imagine"); ?></label></th>
<td>
<div id="taxonomy-image-holder">
<?php if( !empty($category_meta[$tag->term_id]['image']) ) { ?>
<img style="max-width:100%;display:block;" src="<?php echo esc_attr( $category_meta[ $tag->term_id ]['image']['thumb'] ); ?>" alt="Miniatură categorie" title="Miniatură categorie" />
<a id="taxonomy-image-select" class="thickbox" href="media-upload.php?is_term=true&type=image&TB_iframe=1"><?php _e('Schimbă imaginea'); ?></a>
<a class="deletion" id="taxonomy-image-remove" href="#remove-image">Șterge imaginea</a>
<?php } else { ?>
<a id="taxonomy-image-select" class="thickbox" href="media-upload.php?is_term=true&type=image&TB_iframe=1"><?php _e('Alege o imagine'); ?></a>
<?php } ?>
</div>
<input type="hidden" name="category_meta[<?php echo $tag->term_id ?>][image][id]" value="<?php if( isset($category_meta[ $tag->term_id ]['image']['id']) ) echo esc_attr($category_meta[ $tag->term_id ]['image']['id']); ?>" class="tax-image-id" />
<input type="hidden" name="category_meta[<?php echo $tag->term_id ?>][image][thumb]" value="<?php if( isset($category_meta[ $tag->term_id ]['image']['thumb']) ) echo esc_attr($category_meta[ $tag->term_id ]['image']['thumb']); ?>" class="tax-image-thumb" />
<span class="description"><?php _e('O imagine pentru categorie.'); ?></span></td>
</tr>
<?php
}
// necesar pentru încărcarea imaginilor pe ecrane care nu sunt post/pagină
function fix_async_upload_image() {
if(isset($_REQUEST['attachment_id'])) {
$GLOBALS['post'] = get_post($_REQUEST['attachment_id']);
}
}
// avem de-a face cu ecranul de editare a taxonomiei?
function is_category_context() {
if ( isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'],'is_term') !== false ) {
return true;
} elseif ( isset($_REQUEST['_wp_http_referer']) && strpos($_REQUEST['_wp_http_referer'],'is_term') !== false ) {
return true;
} elseif ( isset($_REQUEST['is_term']) && $_REQUEST['is_term'] !== false ) {
return true;
}
return false;
}
// înlocuiți textul "Inserează în Post" cu ceva mai potrivit
function category_image_replace_text_in_thickbox($translated_text, $source_text, $domain) {
if ( is_category_context() ) {
if ('Insert into Post' == $source_text) {
return __('Folosește această imagine', MB_DOM );
}
}
return $translated_text;
}
// afișați un script care setează variabile pe obiectul window pentru a fi accesibile în altă parte
function category_image_send_to_editor( $html, $id, $attachment ) {
// verificarea contextului poate să nu fie necesară și poate să nu funcționeze în toate cazurile
if ( is_category_context() ) {
$item = get_post($id);
$src = wp_get_attachment_image_src($id,'thumbnail',true); // 0 = url, 1 = width, 2 = height, 3 = icon(bool)
?>
<script type="text/javascript">
// trimite variabilele imaginii înapoi la deschizător
var win = window.dialogArguments || opener || parent || top;
win.TI.id = <?php echo $id ?>;
win.TI.thumb = '<?php echo $src[0]; ?>';
</script>
<?php
}
return $html;
}
// scrieți JavaScript-ul care gestionează ce se întâmplă când un utilizator dă click să folosească o imagine
function category_image_send_script() { ?>
<script>
self.TI = {};
var tb_position;
function send_to_editor(h) {
// ignorați conținutul returnat de încărcătorul media și folosiți variabilele transmise la window
jQuery('.tax-image-id').val( self.TI.id );
jQuery('.tax-image-thumb').val( self.TI.thumb );
// afișați imaginea
jQuery('#taxonomy-image-holder img, #taxonomy-image-remove').remove();
jQuery('#taxonomy-image-holder')
.prepend('<img style="max-width:100%;display:block;" src="'+ self.TI.thumb +'" alt="Miniatură categorie" title="Miniatură categorie" />')
.append('<a class="deletion" id="taxonomy-image-remove" href="#remove-image">Șterge imaginea</a>');
jQuery('#taxonomy-image-select').html('Schimbă imaginea');
// închide thickbox
tb_remove();
}
(function($){
$(document).ready(function() {
tb_position = function() {
var tbWindow = $('#TB_window'), width = $(window).width(), H = $(window).height(), W = ( 720 < width ) ? 720 : width;
if ( tbWindow.size() ) {
tbWindow.width( W - 50 ).height( H - 45 );
$('#TB_iframeContent').width( W - 50 ).height( H - 75 );
tbWindow.css({'margin-left': '-' + parseInt((( W - 50 ) / 2),10) + 'px'});
if ( typeof document.body.style.maxWidth != 'undefined' )
tbWindow.css({'top':'20px','margin-top':'0'});
};
return $('a.thickbox').each( function() {
var href = $(this).attr('href');
if ( ! href ) return;
href = href.replace(/&width=[0-9]+/g, '');
href = href.replace(/&height=[0-9]+/g, '');
$(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) );
});
};
$(window).resize(function(){ tb_position(); });
$('#taxonomy-image-select').click(function(event){
tb_show("Alege o imagine:", $(this).attr("href"), false);
return false;
});
$('#taxonomy-image-remove').live('click',function(event){
$('#taxonomy-image-select').html('Alege o imagine');
$('#taxonomy-image-holder img').remove();
$('input[class^="tax-image"]').val("");
$(this).remove();
return false;
});
});
})(jQuery);
</script>
<?php
}
Accesarea informațiilor
În funcția dvs. my_function
din răspunsul dvs., veți accesa metadatele astfel:
function my_function(){
$args=array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories=get_categories($args);
// obțineți metadatele categoriei și ieșiți dacă nu există
$category_meta = get_option('category_meta');
if ( !$category_meta )
return;
echo '<ul style="list-style-type:none;margin:0;padding:0">';
foreach($categories as $category) {
// omiteți categoriile nebifate și categoriile fără metadate
if ( !isset( $category_meta[ $category->term_id ] ) || ( isset( $category_meta[ $category->term_id ] ) && !$category_meta[ $category->term_id ]['show_on_home'] ) )
continue;
echo '<li><a style="display:block;margin-top:20px;" href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "Vezi toate articolele din %s" ), $category->name ) . '" ' . '>' . $category_meta[ $category->term_id ]['title'].'</a>';
if ( "" != $category_meta[ $category->term_id ]['image']['id'] )
echo wp_get_attachment_image( $category_meta[ $category->term_id ]['image']['id'], 'category_thumbnail', false, array( 'alt' => $category->name, 'class' => '' ) );
echo $category->description . '</li>';
}
echo '</ul>';
}

Uau, mulțumesc sanchothefat. Apreciez efortul tău. Am reușit să pun mare parte din el laolaltă singur, dar voi accepta răspunsul tău și voi integra asta în codul meu.

Sanchothefat, meriți recompensa pe care am pus-o pentru asta, ai primit vreuna?

Cât de dificil ar fi să modifici codul tău pentru a salva imaginile într-un director sub uploads numit "category-images"? Și dacă directorul nu există, să-l creeze.

Sincer să fiu, nu sunt sigur. S-ar putea să existe un filtru pentru calea directorului de încărcare. Însă mie îmi place să folosesc biblioteca media încorporată pentru că face încărcările și generarea thumbnail-urilor o joacă de copii. Aruncă o privire la http://adambrown.info/p/wp_hooks - este o resursă excelentă care descrie fiecare hook și filtru din WordPress.
Nu am primit recompensa :( probabil a expirat.

Cea mai ușoară metodă ar fi folosind ceva de genul http://wordpress.org/extend/plugins/category-images/. Sau ai putea să-ți scrii propriul tău hook.

Mulțumesc Wyck, am testat acest plugin dar nu face exact TOATE lucrurile de care am nevoie. De exemplu, nu vreau să înlocuiesc textul linkului cu imaginea, ci doresc atât imaginea CÂT și textul linkului.

Se pare că thumbnail-ul este afișat doar pe pagina single.php a postării. Am nevoie de o listă personalizată de categorii (un fel de pagină de index) pentru toate categoriile. Am actualizat întrebarea mea cu mai multe detalii și am adăugat un bounty pentru o soluție concludentă.

Aici a fost prima mea încercare...
add_filter( 'the_content', 'cb_category_listing' );
function cb_category_listing( $content )
{
if ( is_home() ) {
$cat_args['title_li'] = '';
$cat_args['exclude_tree'] = 1;
$cat_args['exclude'] = 1;
$myContent = wp_list_categories(apply_filters('widget_categories_args', $cat_args));
$content .= $myContent;
}
return $content;
}
Evident, acest cod creează doar o listă cu numele categoriilor și un link către fiecare categorie. Așa că mă ajută să încep. Totuși, mai am nevoie de...
O metodă de a asocia o imagine thumbnail pentru fiecare categorie și de a o afișa în listarea categoriilor din codul de mai sus.
O metodă de a include un titlu personalizat pentru categorie, în afară de numele categoriei, și de a-l afișa în listarea categoriilor (în locul "Numele Categoriei")
O metodă de a afișa/ascunde fiecare categorie din listare. Ideal, cu o casetă de bifat "Afișează în listarea de pe pagina principală" care poate fi editată în ecranul de editare al categoriei.
Iată codul meu actualizat. Aproape am reușit, dar încă nu am rezolvat problema imaginii thumbnail sau adăugarea câmpurilor personalizate (imagine thumbnail, titlu personalizat, afișare/ascundere) în editorul de categorii din administrare...
function _add_my_filter() {
if ( is_home() OR is_sticky() )
{
add_filter( 'the_content', 'my_function' );
}
}
add_action('template_redirect', '_add_my_filter');
function my_function(){
$args=array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories=get_categories($args);
echo '<ul style="list-style-type:none;margin:0;padding:0">';
foreach($categories as $category) {
echo '<li><a style="display:block;margin-top:20px;" href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "Vezi toate articolele din %s" ), $category->name ) . '" ' . '>' . $category->name.'</a>';
echo $category->description . '</li>';
}
echo '</ul>';
}
