Installer

Sur fr.wordpress.org, cliquer sur le bouton bleu "Télécharger Wordpress {version}" à droite ou sur le lien "Télécharger au format .tar.gz."

# exemple en ligne de commande
wget http://fr.wordpress.org/wordpress-3.8.1-fr_FR.tar.gz

Extraire le zip ou le tar.gz à la racine d'un répertoire web. L'archive crée le répertoire wordpress/

tar xzvf wordpress-3.8.1-fr_FR.tar.gz

Créer une base de données.

mysql -u root -p
# entrer le mot de passe
CREATE DATABASE wordpress381 CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON wordpress381.* TO 'wordpress381'@'localhost' IDENTIFIED BY 'wordpress381';

Dans le répertoire wordpress, copier le fichier wp-config-sample.php en wp-config.php et modifier le avec vos renseignements.

cd wordpress
cp wp-config-sample.php wp-config.php
vim wp-config.php
# modifier DB_NAME DB_USER DB_PASSWORD

Modifier aussi les clefs uniques dans le fichier wp-config.php.

Commande vim: r!wget -q https://api.wordpress.org/secret-key/1.1/salt/ -O -

Ouvrir la page d'accueil de wordpress à l'adresse: http://votredomaine.com/wordpress/. Il y aura une redirection automatique vers: http://votredomaine.com/wordpress/wp-admin/install.php

Entrer les informations demandées (titre du site, identifiant, mot de passe, adresse courriel et décocher vie privée) et cliquer sur Enregistrer. Noter bien l'identifiant et le mot de passe choisie.

Connecter vous sur http://votredomaine.com/wordpress/wp-login.php.

Mise à jour

IMPORTANT : Cettre procédure copie le site wordpress d'un répertoire qui ne s'appelle pas wordpress (ex: site/, blogue/, actualite/). Si le répertoire s'appelle wordpress, l'extraction de l'archive écrasera votre site.

# vérifier que l'authentification administrateur fonctionne
http://{DOMAIN}/wp-admin/

# backup mysql
grep DB {directory}/wp-config.php
mysqldump -u {DBUSER} {DBNAME} -p > {site}.{date}.sql

wget http://fr.wordpress.org/wordpress-3.7.1-fr_FR.tar.gz
tar xzvf wordpress-3.7.1-fr_FR.tar.gz

mv wordpress/wp-config-sample.php wordpress/wp-config.php
# copier renseignement de l'ancienne config
vim wordpress/wp-config.php -o {directory}/wp-config.php

# récupération de nouveaux salts
:r!wget -q -O - https://api.wordpress.org/secret-key/1.1/salt/

# theme
cp -R {directory}/wp-content/themes/{THEME}/  wordpress/wp-content/themes/
# files
cp -R {directory}/wp-content/uploads wordpress/wp-content
# .htaccess
cp {directory}/.htaccess wordpress/

# changer les droits si nécessaire
chown -R {user}:{password} wordpress

# étape finale, déplacer ancien dossier, et remplacer le nouveau wordpress/ par {directory}/
mv {directory} {directory}.old
mv wordpress {directory}

# mise à jour bd/système
http://{DOMAIN}/wp-admin/ (devrait rediriger vers http://{DOMAIN}/wp-admin/upgrade.php?_wp_http_referer=%2Fwp-admin%2F

# vérifier affichage site:
http://{DOMAIN}/
http://{DOMAIN}/robots.txt
http://{DOMAIN}/favicon.ico (ou celle spécifiée dans Shortcut Icon)

3.81 vers 4.2

tar czvf wordpress381-backup.tgz wordpress
# grep DB wordpress/wp-config.php
mysqldump -u wordpress -p wordpress > wordpress381-backup.sql

# téléchargement de fichiers, ne pas prendre la version erroné .tar.gz (0.2 Mo)
wget https://fr.wordpress.org/wordpress-4.2.2-fr_FR.zip
mv wordpress wp381
unzip wordpress-4.2.2-fr_FR.zip
cp wp381/wp-config.php wordpress/wp-config.php
# copie des fichiers de wp-content si modifié ou téléchargés

# Réouvrir
/wordpress/wp-admin/update-core.php
# Cliquer sur mettre à jour la base de données
# Cliquer sur continuer

# Se reconnecter

# Effacer wp381
rm -rf wp381

#déplacer backup

3.81 vers 4.1

Archive/backup : http://codex.wordpress.org/fr:WordPress_Backups

tar czvf wordpress381-backup.tgz wordpress
# grep DB wordpress/wp-config.php
mysqldump -u wordpress -p wordpress > wordpress381-backup.sql

/wordpress/wp-admin/update-core.php
Mettre à jour : FTP/FTPS (SSL)

ou téléchargement de fichiers
wget https://downloads.wordpress.org/release/fr_FR/wordpress-4.1.1.zip
mv wordpress wp381
unzip wordpress-4.1.1.zip 
cp wp381/wp-config.php wordpress/wp-config.php
# copie des fichiers de wp-content si modifié ou téléchargés

Réouvrir
/wordpress/wp-admin/update-core.php
Cliquer sur mettre à jour la base de données
Cliquer sur continuer

Se reconnecter

#Effacer wp381
rm -rf wp381

Mise à jour des extensions

Avec la version 3.8.1-fr_FR en date du 2014-03-21, la version livrée par défaut d'askimet 2.5.9 est déjà obsolète, 2.6.0 est sortie. En cliquant sur mettez à jour automatiquement (/wp-admin/update.php?action=upgrade-plugin&plugin=akismet%2Fakismet.php&_wpnonce=), elle sera téléchargé et mis à jour par wordpress, mais seulement en donnant accès à wordpress aux informations FTP. Wordpress ne possède pas de bouton pour annuler cette opération, il faut recliquer sur Extensions.

Puisqu'on ne l'utilise pas et qu'elle n'est pas activée, on peut simplement la Supprimer. Par contre, on ne peut pas supprimer les fichiers (sans l'authentification FTP).

En ligne de commande, il faut aller dans le répertoire /wordpress/wp-content/plugins et supprimer le répertoire askimet (rm -rf askimet).

Pour supprimer Hello Dolly, rm -rf /wordpress/wp-content/plugins/hello.php

Améliorer le référencement/SEO

Par défaut les pages utilisent les paramètres /?p=1. Pour activer le format /2014/03/21/exemple-article/ il faut:

  • Aller dans Réglages > Permaliens (/wp-admin/options-permalink.php).
  • Cliquer sur l'option radio "Date et titre"
  • Cliquer sur le bouton "Enregistrer"
  • Il y a ensuite un avertissement de mettre à jour le fichier .htaccess avec les informations un peu plus bas. Par défaut, le fichier doit être à la racine du site:
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /wordpress/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /wordpress/index.php [L]
    </IfModule>
    
  • Les adresses /?p=1 seront automatiquement redirigés (301) vers la nouvelle adresse.

Meta Keywords, Meta Description

Par défaut les pages ne possèdent pas de meta content="keywords" ni meta content="description".

Les mots-clés dans les articles ne sont pas les keywords mais des "Tags"

La balise Title est le titre de la page | Titre du site

Réglages > Lecture > Visibilité pour les moteurs de recherche est coché = <meta name='robots' content='noindex,follow' />

Il est possible d'utiliser les champs personnalisés en cliquant sur "Options de l'écran" en haut à droite, suivi de [x] Champs personnalisés.

Ensuite, dans la section "Champ personnalisés", on peut cliquer deux fois sur le bouton "Ajouter un champ personnalisé", ajouter metadescription et metakeywords et Mettre à jour les deux champs.

Modifier du thème, fichier "/wordpress/wp-content/themes/twentyfourteen/header.php", après la ligne <?php wp_head(); ?>, ajouter:

<?php
    // for blog post (single) and page (page)
    if ((is_single() || is_page()) && $post && $post->ID) {
         $keyword = get_post_meta($post->ID, 'metakeywords', true);
         $description = get_post_meta($post->ID, 'metadescription', true);
         echo '<meta name="keywords" content="'.htmlspecialchars($keyword).'" />';
         echo '<meta name="description" content="'.htmlspecialchars($description).'" />';
    }
?> 

Avec cette technique, les metas seront ceux du premier contenu même dans les listes ou les recherches. Pour éviter ce problème, on peut ajouter is_single() dans les conditions. Voir Conditional_Tags pour la liste des fonctions qui débutent par is_...()

Thèmes

  • twentyfifteen : demo
  • twentyfourteen : demo
  • twentythirteen : demo
  • twentytwelve : demo
  • twentyeleven : demo

Analyse themes

Répertoire: /wp-content/themes/nomtheme/

Fichier gabarit:

Points d'entrée:
index.php - page d'accueil
404.php - si la page n'est pas trouvée
archive.php - page archivée
author.php  - page liste pour un auteur
category.php - page liste pour une catégorie
image.php - page pour les images attachées
page.php - page individuelle
search.php - résultat de recherche
showcase.php - ?
sidebar-page.php -  ?
single.php - ?
tag.php - page liste par tags

Éléments graphique:
header.php # doit être inclus avec get_header()
footer.php # doit être inclus avec get_footer()
sidebar.php # doit être inclus avec get_sidebar()

Toujours inclus:
functions.php # inclus automatiquement sur toutes les pages

?
(for all comments)
comments.php # comments_template('', true)
searchform.php # get_search_form()

Astuce (pas dans le fonctionnement normal)
==========================================
Post format (for each article) : get_template_part( 'content', get_post_format() );
content-aside.php
content-featured.php
content-gallery.php
content-image.php
content-intro.php
content-link.php
content-page.php
content.php # default
content-quote.php
content-single.php
content-status.php

sidebar: get_sidebar('name')
sidebar-footer.php # template de get_sidebar('footer')

Fonctions utilitaires

__('EnglishWord') ou __('EnglishWord', 'section') : traduction

Affichages (echo)

HTML attributes:
language_attributes()
body_class() 

HTML encoded string
_e('English String', 'translation-category')
bloginfo('aKey') # see get_bloginfo()
esc_attr_e('English String', 'translation-category')
get_search_form() # inclus searchform.php
get_sidebar('name') # inclus sidebar-name.php
get_template_part('name', 'part') # inclus name-part.php
header_image()
wp_footer()
wp_title('aSep',true,'right')
wp_nav_menu(...)

Retourne une chaîne

Non HTML encoded string
home_url('/')
get_bloginfo('name', 'display')
TEMPLATEPATH (current full template path without ending /)

HTML encoded string
est_attr()
esc_url()
get_bloginfo('charset')
get_bloginfo('description','display')
get_bloginfo('description')
get_bloginfo('name')
get_bloginfo('pingback_url')
get_bloginfo('stylesheet_url')
get_header_image()
get_header_textcolor()
get_option('thread_comments')
get_template_directory_uri()

Retourne un booléen

is_home()
is_front_page()
is_singular
has_post_thumbnail($postID)

Analyse option

Note 1: wordpress maintient un tableau des options qui ne sont pas dans la base de données (notoptions) et fait des vérifications à toutes les fois
Note 2: wordpress fait d'autre traitement aussi pour filtrer chaque option avec pre_option_$option (avant) et option_$option (apres)
        en plus d'enlever des slash et autre hack...

get_option($option, $default = false) { }
-­ wp_load_alloptions()
- if present in all options:
  - get it
- else
  - get it in cache
  - if not in cache
    - get it in database
    - add it to the cache

update_option
- enregistre dans la base de données
- met à jour le cache

wp_load_alloptions() 
- regarde dans le cache 'alloptions'
- si pas dans le cache
  - aller chercher toutes les options dans la base de données
  - mettre en cache

Hacked by Badi

2013-02-23

Je suis tombé par hasard sur un wordpress infecté.

Je n'ai pas vu de fichier PHP modifié sur le serveur mais j'ai vu ces clés dans la table MySQL wp_options.

blogname
+ADw-/title+AD4-Hacked By Badi+ADw-DIV style+AD0AIg-DISPLAY: none+ACIAPgA8-xmp+AD4-
 
widget_text
a:2:{i:2;a:3:{s:5:"title";s:0:"";s:4:"text";s:109:"<script>document.documentElement.innerHTML = unescape('%48%61%63%6b%65%64%20%42%79%20%42%61%64%69');</script>";s:6:"filter";b:0;}s:12:"_multiwidget";i:1;}
 
blog_charset
UTF-7

Le nom du blog est affiché dans le titre. Le widget_text affiche Hacked By Badi. Je n'ai pas encore trouvé de piste sur l'origine du hack. Certains parlent d'une attaque sur le serveur Web même. J'ai remplacé avec PHPMyAdmin les trois options par:

blogname
Titre du blogue

widget_text
a:2:{i:2;a:3:{s:5:"title";s:0:"";s:4:"text";s:0:"";s:6:"filter";b:0;}s:12:"_multiwidget";i:1;}

blog_charset
UTF-8

Fichier .htaccess

Exemple si le répertoire wordpress se nomme /actualites/ et que le fichier est /actualites/.htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /actualites/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /actualites/index.php [L]
</IfModule>

# END WordPress

javascript

jquery

jQuery.noConflict() est souvent utilisé et donc $ n'est pas définie. On peut utiliser un IIFE, si on veut continuer à utiliser $.

(function($) {
  // code avec $
})(jQuery);