Tips Wordpress

Retrouvez les tips qui peuvent servir pour Wordpress

Force update of NSN theme/plugin that is not detected by WP for some reason → Debug Bar

Liste des hook filter disponible sur Wordpress :

https://adambrown.info/p/wp_hooks/hook

Plugins debug

function wpdb() { global $wpdb; return $wpdb; } var_dump(wpdb()->num_queries , wpdb()->queries);

Optimise wp query

'update_post_term_cache' => false, // grabs terms, remove if terms required (category, tag...)
'update_post_meta_cache' => false, // grabs post meta, remove if post meta required

Add CPT to Sitemap

function enable_custom_sitemap() {
    global $wpseo_sitemaps;
    if ( isset( $wpseo_sitemaps ) && ! empty ( $wpseo_sitemaps ) ) {
        $wpseo_sitemaps->register_sitemap( 'clubs', 'create_recipe_sitemap' );
    }
}
add_action( 'init', 'enable_custom_sitemap' );

Tips SQL

Supprimer les revisions pour alleger la BDD

DELETE a,b,c FROM wp_posts a 
LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) 
LEFT JOIN wp_postmeta c ON (a.ID = c.post_id) 
WHERE a.post_type = 'revision'

Tags

Exporter Tags / category

SELECT *
FROM Edks_terms as t LEFT JOIN Edks_term_taxonomy as tt on t.term_id = tt.term_id
WHERE tt.taxonomy="post_tag" 

SELECT *
FROM Edks_terms as t LEFT JOIN Edks_term_taxonomy as tt on t.term_id = tt.term_id
WHERE tt.taxonomy="category"

Liste tags et catégories avec slug / count

Via phpmyadmin :

SELECT name, slug, taxonomy FROM wpp_term_taxonomy NATURAL JOIN wpp_terms WHERE taxonomy="post_tag" OR taxonomy="category"

SELECT name, slug, count FROM `wp_term_taxonomy` NATURAL JOIN wp_terms WHERE taxonomy="post_tag";

Via wp cli :

wp term recount category post_tag

wp term list post_tag --format=csv > all_tags.csv

wp term list category --format=csv > all_cats.csv

Supprimer Tags by slug

a partir du excel / txt qu'on vous envoie generez une liste

DELETE t, tt
FROM Edks_terms as t LEFT JOIN Edks_term_taxonomy as tt on t.term_id = tt.term_id
WHERE tt.taxonomy="post_tag" AND t.slug in (
	'18-ko)',
	'17-ko)',
	'10-ko)',
	'"chino"-rivas',
	'_patrik-kammins',
	'37-ko)-i-marko-huk-(40-4-1',
	'-a1-wgp',
	'abdula-abdulvahabov',
	'abdulmalik-gadzhi-chalambiev',
	'abdulmanap-magomedov',
	'abdul-rahman-dudaev'
)

## À partir d'une table :
 
DELETE a,b,c,d FROM wp_terms a 
LEFT JOIN wp_term_taxonomy b ON (a.term_id = b.term_id) 
LEFT JOIN wp_term_relationships c ON (c.term_taxonomy_id = b.term_taxonomy_id)
LEFT JOIN wp_termmeta d ON (a.term_id = d.term_id) 
WHERE a.slug IN (SELECT * FROM tag_to_delete) AND b.taxonomy="post_tag";

Supprimer Categories by slug

DELETE t, tt
FROM Edks_terms as t LEFT JOIN Edks_term_taxonomy as tt on t.term_id = tt.term_id
WHERE tt.taxonomy="category" AND t.slug in (
	'slug-category'
)

Remplacer les espaces dans les slugs des tags par des tirets

UPDATE Edks_terms SET slug = REPLACE(slug, ' ', '-');

Suppression des tags avec X posts au max

DELETE FROM wp_terms WHERE term_id IN (SELECT term_id FROM wp_term_taxonomy WHERE count <= 30 );
DELETE FROM wp_term_taxonomy WHERE term_id not IN (SELECT term_id FROM wp_terms);
DELETE FROM wp_term_relationships WHERE term_taxonomy_id not IN (SELECT term_taxonomy_id FROM wp_term_taxonomy);

DELETE Tags whith less than 20 posts without impacting menu

DELETE a,b,c FROM wp_term_relationships a 
NATURAL JOIN wp_term_taxonomy b 
NATURAL JOIN wp_terms c 
WHERE count<20 AND taxonomy="post_tag";

Category

DELETE categories from post list by slug

DELETE a FROM wp_term_relationships a
LEFT JOIN wp_posts b ON (b.ID = a.object_id) 
 WHERE b.post_name IN (
'player-ratings-chelsea-3-1-arsenal',
'are-arsenal-more-than-just-mesut-ozil-and-alexis-sanchez',
'arsenal-need-drop-mesut-ozil-save-season',
'fw-tv-arsenal-belotti-wenger-torino',
)

Add category to a post

INSERT into wp_term_relationships (object_id, term_taxonomy_id, term_order) 
SELECT p.ID, 149793, 0 
FROM wp_posts p  
WHERE p.post_name = 'yahoo-sports-daily-fantasy-football-the-weekends-top-performers';

Resync count posts in all categories

      $update_taxonomy = 'category';
			$get_terms_args = array(
			    'taxonomy' => $update_taxonomy,
			    'fields' => 'ids',
			    'hide_empty' => false,
			);
			
			$update_terms = get_terms($get_terms_args);
			wp_update_term_count_now($update_terms, $update_taxonomy);

Liste catégories utilisées dans un menu:

SELECT * FROM cdatb_term_taxonomy b NATURAL JOIN cdatb_terms c WHERE taxonomy="category" AND (term_id IN (SELECT meta_value FROM cdatb_postmeta WHERE meta_key LIKE '_menu_item_object_id'));

Liste post from catégories + cat enfant:

SELECT post_name, a.name FROM wp_terms a LEFT JOIN wp_term_taxonomy b ON (a.term_id = b.term_id) LEFT JOIN wp_term_relationships c ON (c.term_taxonomy_id = b.term_taxonomy_id) LEFT JOIN wp_posts d ON (c.object_id = d.ID) WHERE a.slug IN ("poker","cassino-online") or parent=3171

Content

REGEX Search and replace

Exemple : remplace les liens talksport et garde uniquement l'ancre

SELECT post_content, 
REGEXP_REPLACE(post_content, '/<a.*href="(.*)talksport\.com(.*)>(.*)</a>/gms', '\\3') as post_replace 
FROM wp_posts 
where post_content REGEXP 'talksport.com/'

Regex remplacer liens OU iframe

UPDATE wp_posts 
SET post_content = REGEXP_REPLACE(post_content,'<(a|iframe)(.*)(href|src)="https://www.strikeout.nu/oleksandr-usyk-vs-tyrone-spong-stream-2(.*)>(.*)</(a|iframe)>', '' ) 
WHERE `post_content` LIKE "%https://www.strikeout.nu/oleksandr-usyk-vs-tyrone-spong-stream-2%";

Remplacer liens internes

Version Automatisation SQL :

PREPARATION

  1. Créer la table url_to_update avec 2 champs "vieux" et "nouv" varchar 255
  1. Procedure SQL à ajouter à la base de données (attention au préfix de table)
    DELIMITER $$
    CREATE PROCEDURE UpdateUrl(
        oldlink VARCHAR(255),
        newlink VARCHAR(255)
    )
    BEGIN
        UPDATE wp_posts 
        SET post_content = REGEXP_REPLACE(post_content,oldlink,newlink)
        WHERE `post_type` IN ('post', 'page') AND post_status='publish' AND post_content LIKE CONCAT('%',oldlink,'%');
    END$$ 
    DELIMITER ;
  1. Trigger SQL à ajouter à la table url_to_update
    DELIMITER $$
    CREATE TRIGGER insert_url_to_update
    AFTER INSERT
    ON url_to_update FOR EACH ROW
    BEGIN
        CALL Updateurl (NEW.vieux,NEW.nouv);
    END$$
    DELIMITER ;

UTILISATION

  1. Importer les urls à modifier dans la table url_to_update
  1. Vérifier que les urls ont bien étaient modifiées dans post_content
  1. Vider url_to_update

Version fonction PHP:

UPDATE wp_posts 
SET post_content = REPLACE(post_content, 'https://nomdusite.com/ancien-lien.html', 'https://nomdusite.com/nouveau-lien.html')
WHERE post_content LIKE '%https://nomdusite.com/ancien-lien.html%';

Utilisation dans une fonction après avoir importé les url dans une table url_to_update (champs old, new) de la BDD

function update_url(){
global $wpdb;
// limite à 5 pour pas surcharger le serveur
$results = $wpdb->get_results("SELECT * FROM url_to_update LIMIT 5");
if (empty($results)){
return false;
}
else{
foreach ($results as $result) {
$q=$wpdb->get_results("UPDATE wp_posts SET post_content = REGEXP_REPLACE(post_content,$result->old, $result->new) WHERE post_content LIKE '%".$result->old."%'");
$wpdb->get_results("DELETE FROM url_to_update WHERE old='".$result->old."'");
}
}
}
//if (is_admin()) update_url();

Suppression liens internes

Version Automatisation SQL :

PREPARATION

⚠️
Attention a remplacer les “/” par “\\/” dans les URLs du fichier fourni. Et ausis supprimer les doublons d’URL pour éviter que l’insertion ne prenne plus de temps que nécessaire (Excel Données → Supprimer doublons → choisir la bonne colonne)
  1. Créer la table url_to_delete avec 1 champ "url" varchar 255
  1. Procedure SQL à ajouter à la base de données (attention au préfix de table)
    DELIMITER $$
    CREATE PROCEDURE DelUrl(link VARCHAR(255))
    BEGIN
    DECLARE pattern VARCHAR(255);
    SET pattern = CONCAT('<a(.*) href="',link,'"(.*)>(.*)</a>');
    UPDATE wp_posts
    SET post_content = REGEXP_REPLACE(post_content,pattern,'\\3')
    WHERE `post_type` IN ('post', 'page') AND post_status='publish' AND post_content LIKE CONCAT('%',link,'%');
    END$$ 
    DELIMITER ;

Runstack (pas besoin d’échapper les url)

DELIMITER $$
CREATE PROCEDURE DelUrl(link VARCHAR(255))
BEGIN
DECLARE pattern VARCHAR(255);
SET pattern = CONCAT(CAST('<a(.*) href="' AS CHAR CHARACTER SET utf8),CAST(link AS CHAR CHARACTER SET utf8),CAST('"(.*)>(.*)</a>' AS CHAR CHARACTER SET utf8));
UPDATE Edks_posts
SET post_content = REGEXP_REPLACE(CAST(post_content AS CHAR CHARACTER SET utf8),pattern,'3')
WHERE post_content LIKE CONCAT(CAST('%' AS CHAR CHARACTER SET utf8),CAST(link AS CHAR CHARACTER SET utf8),CAST('%' AS CHAR CHARACTER SET utf8));
END$$ 
DELIMITER ;
  1. Trigger SQL à ajouter à la table url_to_delete
    DELIMITER $$
    CREATE TRIGGER insert_url_to_delete
    AFTER INSERT
    ON url_to_delete FOR EACH ROW
    BEGIN
    CALL Delurl (NEW.url);
    END$$
    DELIMITER ;

UTILISATION

  1. Insérer les urls à supprimer dans la table url_to_delete
  1. Vérifier que les urls ne sont plus présentes dans post_content
  1. Vider url_to_delete

Version fonction PHP:

UPDATE wp_posts 
SET post_content = REGEXP_REPLACE(post_content,'<a(.*)href="https://nomdusite.com/lien-a-supprimer.html(.*)>(.*)</a>', '\\3') 
WHERE `post_content` LIKE '%https://nomdusite.com/lien-a-supprimer.html%';

Utilisation dans une fonction après avoir importé les url dans une table url_to_delete (champs url) de la BDD

function del_url(){
            global $wpdb;
						// limite à 5 pour pas surcharger le serveur
            $results = $wpdb->get_results("SELECT * FROM `url_to_delete` LIMIT 5");
            if (empty($results)){
                return false;
            }
            else{
                foreach ($results as $result) {
                    $q=$wpdb->get_results("UPDATE wp_posts SET post_content = REGEXP_REPLACE(post_content,'<a(.*)href=\"".$result->url."(.*)>(.*)</a>', '\\\\3') WHERE `post_content` LIKE '%".$result->url."%'");
                    $wpdb->get_results("DELETE FROM url_to_delete WHERE url='".$result->url."'");
                }
            }
        }
//if (is_admin()) del_url();

DELETE post/page from BDD

DELETE a,b,c FROM wp_posts a 
LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) 
LEFT JOIN wp_postmeta c ON (a.ID = c.post_id) 
WHERE a.post_name = 'tottenham-1-2-juventus-5-things-we-learned';
	DELETE a,b,c FROM wp_posts a 
	LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) 
	LEFT JOIN wp_postmeta c ON (a.ID = c.post_id) 
	WHERE a.post_name IN (SELECT * FROM post_to_delete);

Replace Native post slug in BDD

UPDATE Edks_posts P, slug_to_update S 
SET P.post_name = S.new_slug 
WHERE P.post_name = S.old_slug;

No shortcode in extract

function nsn_remove_shortcode_from_extract($content) {   
    $content = strip_shortcodes( $content );      
    return $content;
} 
add_filter('the_excerpt', 'nsn_remove_shortcode_from_extract');

Solution pour l’erreur “preg_match(): Compilation failed: invalid range in character

     preg_match('/[\w-.]+/', ''); // this will not work in PHP7.3
DEVIENT :
		 preg_match('/[\w\-.]+/', ''); // the hyphen needs to be escaped

Images

Script bash pour créer la balise alt sur des images

post_table=wpp_posts
postmeta_table=wpp_postmeta
failed=0
while IFS=, read -r col1 col2
do
    id=$(wp db query "SELECT id FROM $post_table WHERE guid LIKE '$col1' AND post_type LIKE 'attachment'" --skip-column-names)
    if [ -n "$id" ]; then
        wp db query "INSERT INTO $postmeta_table (meta_id, post_id, meta_key, meta_value) VALUES (NULL, $id, '_wp_attachment_image_alt', '$col2')"
        echo "alt metadata has been created for $id"
    else
        echo "$col1 not found";
        ((failed+=1))
        echo "$col1" >> failed_alts.txt
    fi
done < missingalts.csv

echo "fail number: $failed";

Pour que ça fonctionne, il vous fait un csv de ce type =

Si jamais votre fichier excel contient des dimensions dans dans l'url de l'image, utiliser ce regex dans l'excel en créant une seconde colonne (merci Jo)

=REGEXREPLACE(A2;"(-[0-9]{3,4}x[0-9]{3,4})";"")
=REGEXREPLACE(A2;".*([-a-z-A-Z-0-9](.png|.jpg))$";"$1") // fi-plus-10.png 
// <img.*src=".*fi-plus-10.png.* />

Add alt = post title to thumbnail

add_filter( 'post_thumbnail_html', 'default_alt', 20, 5 );
function default_alt( $html, $post_id, $post_thumbnail_id, $size, $attr ){
(is_array($attr)) ? $attr['alt']=get_the_title($post_id) : $attr=array('alt'=> get_the_title($post_id));
$html = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr );
return $html;
}

Suppression des images dans le contenu

Version Automatisation SQL :

PREPARATION

  1. Créer la table img_to_delete avec 1 champ "url" varchar 255
  1. Procedure SQL à ajouter à la base de données (attention au préfix de table)
    DELIMITER $$
    CREATE PROCEDURE DelUrl(link VARCHAR(255))
    BEGIN
    DECLARE pattern VARCHAR(255);
    SET pattern = CONCAT('<img(.*) src="',imglink,'"(.*)>');
    UPDATE wp_posts
    SET post_content = REGEXP_REPLACE(post_content,pattern,'')
    WHERE `post_type` IN ('post', 'page', 'revision')  AND post_content LIKE CONCAT('%',imglink,'%');
    END$$ 
    DELIMITER ;
  1. Trigger SQL à ajouter à la table img_to_delete
    DELIMITER $$
    CREATE TRIGGER insert_img_to_delete
    AFTER INSERT
    ON url_to_delete FOR EACH ROW
    BEGIN
    CALL DelImg (NEW.url);
    END$$
    DELIMITER ;

UTILISATION

  1. Insérer les urls à supprimer dans la table img_to_delete
  1. Vérifier que les urls ne sont plus présentes dans post_content
  1. Vider img_to_delete

Pagination & Offset

Problème :

l' argument de décalage est en fait la valeur que WordPress utilise pour gérer la pagination elle-même. Si un développeur définit une valeur de décalage manuelle, la pagination ne fonctionnera pas car cette valeur remplacera l'ajustement automatique de WordPress du décalage pour une page donnée.

Solution :

Afin d'utiliser un décalage dans les requêtes WordPress sans perdre les fonctionnalités de pagination de WordPress, vous devrez gérer manuellement certains calculs de pagination de base

Remove slash from pagination url

     add_filter('paginate_links','untrailingslashit'); 

Remove post to stemap (YOAST)

     /**
 * Excludes posts from XML sitemaps.
 *
 * @return array The IDs of posts to exclude.
 * source : https://developer.yoast.com/features/xml-sitemaps/api/#exclude-specific-posts
 */
function exclude_posts_from_xml_sitemaps() {
    return [ 1, 2, 3 ];
}

add_filter( 'wpseo_exclude_from_sitemap_by_post_ids', 'exclude_posts_from_xml_sitemaps' );

Filter List Items in YOAST SEO Schema JSON

// Remove un unwanted item/category in the JSON schema
add_filter( 'wpseo_breadcrumb_links', 'breadcrumbs_from_schema', 10 );
function breadcrumbs_from_schema( $pieces ) {
     foreach($pieces as $k=>$v) {
        if($v['text'] == '[Category Name]') {
            unset($pieces[$k]);
        }
    }
     return $pieces;
}

WordPress Hierachy Template file

$per_page = get_option( 'posts_per_page' );
$default_offset = $your_offset_number;
if ($paged == 1) {
  $offset = $default_offset;
} else {
  $offset = (($paged - 1) * $per_page) + $default_offset;
}

Disqus

À la suppression laisse des variables dans la table options. Pour virer les widgets disqus il faut supprimer la variable mvp_disqus_id

Double Redirection → 1 redir HTTPS

RewriteEngine On

RewriteCond %{HTTP_HOST} ^www.goalballlive\.com [NC]

RewriteRule ^(.*)$ https://goalballlive.com/$1 [L,R=301]

https://dash.cloudflare.com/bac22b81509bc6d97205b0bdb42eda4e/goalballlive.com/ssl-tls/edge-certificates

desactiver :

Réécritures HTTPS automatiques

Toujours utiliser HTTPS

laisser le .htaccess faire son boulot

SSL -> NON WWW dans le .htacesss en hot prio 

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

https://patchstack.com/database/

étendre des liens en JS (SEO) → https://www.hteumeuleu.fr/faire-un-lien-sur-toute-une-zone-en-css/

document.addEventListener('DOMContentLoaded', function() {
	var items = document.querySelectorAll('.item');
	for(var i=0; i < items.length; i++) {
		var item = items[i];
		item.addEventListener('click', function() {
			var url = this.getElementsByTagName('a');
			if(url.length > 0)
				url = url[0];
			window.location = url;
		});
	}
});

// OU

document.addEventListener('DOMContentLoaded', function() {
	const items = document.querySelectorAll('.class');
	items.forEach(item => {
	  const url = item.getElementsByTagName('a');
	  if (url[0]) {
	    item.addEventListener('click', function() {
	      window.location = url[0].href;
	    });
	  }
	});
});