Primer pada Ajax di WordPress Frontend: benar-benar melakukannya
() translation by (you can also view the original English article)
Dalam seri ini, kita membahas bagaimana menerapkan Ajax di WordPress frontend. Dalam post pertama dalam seri, kami memeriksa bagaimana Ajax bekerja pada high-level, meninjau bagaimana memperkenalkan Ajax ke Dashboard WordPress, dan meninjau kait dua tersedia untuk menggabungkan Ajax ke WordPress.
Pada titik ini, itu adalah waktu untuk benar-benar membangun sesuatu yang akan menunjukkan bagaimana kita dapat menggunakan Ajax di WordPress frontend. Untuk melakukan ini, kita akan menulis kita sendiri plugin yang memastikan bahwa kita mengikuti praktik terbaik WordPress sepanjang jalan.
Pada akhir artikel ini, kita akan memiliki sebuah plugin yang sepenuhnya bekerja dengan kode sumber yang tersedia untuk umum di GitHub. Dengan mengatakan bahwa, mari kita mulai.
Perencanaan itu keluar
Jika Anda telah membaca salah satu artikel saya sebelumnya, maka Anda tahu bahwa saya selalu suka untuk memulai proyek-proyek saya merencanakan apa yang akan kita lakukan. Proyek ini tidak berbeda.
Dalam contoh ini, kita akan memperkenalkan kotak centang yang memungkinkan pembaca yang login ke WordPress situs untuk memeriksa off posting blog yang mereka sudah baca. Dengan cara ini, mereka akan hanya melihat post yang belum mereka baca sejak login ke situs.
Untuk membangun ini, kita akan menggunakan beberapa hal:
- Instalasi baru Wordpress
- WordPress tema Unit Test untuk menyediakan kami dengan banyak contoh konten
- Twenty Eleven tema (karena begitu banyak tersedia)
- Account pengguna yang memiliki peran 'Subscriber'
Setelah Anda memiliki setup lingkungan, berikut adalah rencana aksi yang kita akan diikuti untuk plugin kami:
- Kita akan menciptakan sebuah plugin baru di direktori plugins yang dinamai I've Read This (dalam direktori ive-read-this)
- Pada setiap posting, kami akan memperkenalkan sebuah kotak centang dan label yang memungkinkan pengguna untuk menandakan bahwa mereka sudah membaca post ini
- Setelah post telah ditandai sebagai telah dibaca, pilihan akan hilang dari view
Mengerti? Silahkan login sebagai pengguna yang Anda buat dengan 'Subscriber' peran dan mari kita mulai!
Membuat I've Read This
Setelah Anda punya data pengujian yang diimpor, Anda setup akan terlihat seperti ini:



Dari sini, kita sudah siap untuk memulai menulis plugin.
Stubbing Plugin
Sebelum kita benar-benar menulis kode apapun, saya ingin pergi ke depan dan stub file plugin. Ini berarti bahwa kita akan setup direktori, struktur dasar plugin dan setiap direktori yang kami mungkin perlu untuk menggunakan plugin dependensi.
Karena kami akan memberikan light styling juga file JavaScript untuk memulai request Ajax, di sini 's apa struktur direktori dasar akan terlihat seperti. Direktori lang opsional, walaupun saya mempertimbangkan penerapan terbaik:



Sekarang, mari kita stub teks yang diperlukan untuk plugin.php. Catatan bahwa ini akan menjadi ahanya kecuali sebuah kerangka. Ini akan menjadi terutama bertanggung jawab untuk meletakkan dasar bagi apa yang kita akan membangun kemudian dalam artikel:
1 |
|
2 |
<?php
|
3 |
/*
|
4 |
Plugin Name: I've Read This
|
5 |
Plugin URI: http://github.com/tommcfarlin/ive-read-this/
|
6 |
Description: A simple plugin for allowing site members to mark when they've read a post.
|
7 |
Version: 1.0
|
8 |
Author: Tom McFarlin
|
9 |
Author URI: http://tommcfarlin.com/
|
10 |
Author Email: tom@tommcfarlin.com
|
11 |
License:
|
12 |
|
13 |
Copyright 2012 Tom McFarlin (tom@tommcfarlin.com)
|
14 |
|
15 |
This program is free software; you can redistribute it and/or modify
|
16 |
it under the terms of the GNU General Public License, version 2, as
|
17 |
published by the Free Software Foundation.
|
18 |
|
19 |
This program is distributed in the hope that it will be useful,
|
20 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 |
GNU General Public License for more details.
|
23 |
|
24 |
You should have received a copy of the GNU General Public License
|
25 |
along with this program; if not, write to the Free Software
|
26 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
27 |
|
28 |
*/
|
29 |
|
30 |
class IveReadThis { |
31 |
|
32 |
/*--------------------------------------------*
|
33 |
* Constructor
|
34 |
*--------------------------------------------*/
|
35 |
|
36 |
/**
|
37 |
* Initializes the plugin by setting localization, filters, and administration functions.
|
38 |
*/
|
39 |
function __construct() { |
40 |
|
41 |
load_plugin_textdomain( 'ive-read-this', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); |
42 |
|
43 |
// Register site styles and scripts
|
44 |
add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_styles' ) ); |
45 |
add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_scripts' ) ); |
46 |
|
47 |
} // end constructor |
48 |
|
49 |
/**
|
50 |
* Registers and enqueues plugin-specific styles.
|
51 |
*/
|
52 |
public function register_plugin_styles() { |
53 |
|
54 |
wp_register_style( 'ive-read-this', plugins_url( 'ive-read-this/css/plugin.css' ) ); |
55 |
wp_enqueue_style( 'ive-read-this' ); |
56 |
|
57 |
} // end register_plugin_styles |
58 |
|
59 |
/**
|
60 |
* Registers and enqueues plugin-specific scripts.
|
61 |
*/
|
62 |
public function register_plugin_scripts() { |
63 |
|
64 |
wp_register_script( 'ive-read-this', plugins_url( 'ive-read-this/js/plugin.js' ), array( 'jquery' ) ); |
65 |
wp_enqueue_script( 'ive-read-this' ); |
66 |
|
67 |
} // end register_plugin_scripts |
68 |
|
69 |
} // end class |
70 |
|
71 |
new IveReadThis(); |
72 |
?>
|
Pada titik ini, Anda dapat benar-benar mengaktifkan plugin di WordPress plugin dasbor, meskipun tidak benar-benar akan terjadi. Jika Anda bangun untuk itu, pergi ke depan dan melakukan itu sekarang - Anda akan dapat menonton plugin yang datang untuk hidup saat kami bekerja di atasnya.
Memperkenalkan sebuah kotak centang pada setiap post
Karena kita akan memperkenalkan sebuah kotak centang pada setiap post yang memungkinkan pengguna untuk beralih apakah atau tidak mereka sudah membaca post, kita harus memperhitungkan berikut:
- Kami perlu memastikan bahwa kotak centang hanya ditampilkan ketika pengguna log in
- Kotak centang harus di bagian bawah post di halaman satu posting karena itulah mana pengguna akan menandai bahwa mereka pernah membaca post
Kita dapat mencapai kedua dengan menambahkan fungsi berikut:
1 |
|
2 |
/**
|
3 |
* Adds a checkbox to the end of a post in single view that allows users who are logged in
|
4 |
* to mark their post as read.
|
5 |
*
|
6 |
* @param $content The post content
|
7 |
* @return The post content with or without the added checkbox
|
8 |
*/
|
9 |
public function add_checkbox( $content ) { |
10 |
|
11 |
// We only want to modify the content if the user is logged in
|
12 |
if( is_user_logged_in() && is_single() ) { |
13 |
|
14 |
// Build the element that will be used to mark this post as read
|
15 |
$html = '<div id="ive-read-this-container">'; |
16 |
$html .= '<label for="ive-read-this">'; |
17 |
$html .= '<input type="checkbox" name="ive-read-this" id="ive-read-this" value="0" />'; |
18 |
$html .= __( "I've read this post.", 'ive-read-this' ); |
19 |
$html .= '</label>'; |
20 |
$html .= '</div><!-- /#ive-read-this-container -->'; |
21 |
|
22 |
// Append it to the content
|
23 |
$content .= $html; |
24 |
|
25 |
} // end if |
26 |
|
27 |
return $content; |
28 |
|
29 |
} // end add_checkbox |
Membaca komentar dengan hati-hati karena mereka harus menjelaskan persis apa yang terjadi; Namun, jika Anda tidak jelas, jangan ragu untuk meninggalkan komentar.
Selanjutnya, kita perlu menambahkan baris berikut di konstruktor sehingga filter the_content
tersebut menjadi:
1 |
|
2 |
// Setup the action for rendering the checkbox
|
3 |
add_filter( 'the_content', array( &$this, 'add_checkbox' ) ); |
Akhirnya, mari kita tambahkan sedikit style hanya untuk memberikan kotak centang yang agak unik tampilan dan nuansa dalam konteks Twenty Eleven tema. Dalam plugin plugin.css file, tambahkan kode berikut:
1 |
|
2 |
#ive-read-this-container { |
3 |
margin: 1em 0 1em; |
4 |
background: #eee; |
5 |
border: 1px solid #ccc; |
6 |
padding: 0.25em; |
7 |
}
|
Sekarang, jika Anda masuk ke instalasi WordPress dan menavigasi ke bagian bawah satu post, Anda harus melihat sesuatu seperti gambar berikut:



Pada titik ini, kita sudah siap untuk mulai menulis beberapa JavaScript.
Membuat request: Setup Handler klik untuk kotak centang
Hal pertama yang perlu kita lakukan adalah untuk setup JavaScript sehingga hanya menjalakan jika wadah "'ve Read This" pada halaman. Ada berbagai cara untuk melakukan ini, tetapi karena kita memuat JavaScript pada setiap halaman, kemudian kita akan menggunakan JavaScript untuk memeriksa keberadaan "'ve Read This" kotak centang yang kami menulis ke halaman.
Untuk melakukannya, tambahkan kode berikut untuk plugin.js. Komentar kode harus jelas. Jika tidak, meninggalkan komentar!
1 |
|
2 |
(function ($) { |
3 |
$(function () { |
4 |
|
5 |
// If the "I've Read This Container" is on this page, let's setup the event handler
|
6 |
if(1 === $('#ive-read-this-container').length) { |
7 |
} // end if |
8 |
|
9 |
});
|
10 |
}(jQuery)); |
Dalam kode yang Anda lihat di atas, apa pun yang kita menempatkan dalam bergantung hanya akan dijalankan jika "'ve Read This" wadah elemen hadir.
Dalam kasus ini, kita tahu bahwa kita perlu mengirim ID dari post ke server. Karena user tersebut login, kita akan mampu mendapatkan ID pada sisi server.
Jadi, langkah berikutnya adalah untuk mendapatkan ID dari post yang kita berada di. Untungnya, Twenty Eleven menyedikan jumlah posting di elemen article
ID. Kita hanya perlu untuk mengurai keluar.
Mari kita lakukan sekarang:
1 |
|
2 |
// We use the change attribute so that the event handler fires
|
3 |
// whenever the checkbox or its associated label are clicked.
|
4 |
$('input[name="ive-read-this"]').change(function (evt) { |
5 |
|
6 |
// We can retrieve the ID of this post from the <article>'s ID. This will be required
|
7 |
// so that we can mark that the user has read this particular post and we can hide it.
|
8 |
var sArticleId, iPostId; |
9 |
|
10 |
// Get the article ID and split it - the second index is always the post ID in Twenty Eleven
|
11 |
sArticleId = $("article").attr('id'); |
12 |
iPostId = parseInt(sArticleId.split('-')[1]); |
13 |
|
14 |
});
|
Pada titik ini, kita sudah siap untuk men-setup request Ajax. Kita akan menggunakan jQuery's $.post
metode untuk melakukan hal ini dan kita akan menggunakan WordPress' standar ajaxurl
untuk menangani respon kita.
Penanganan Event: menandai posting sebagai telah dibaca
Mari kita pergi ke depan dan menulis kode yang akan mengirimkan ID dari post seluruhnya. Kita akan khawatir tentang respon nanti dalam artikel ini, maka "TODO" komentar dalam kode.
1 |
|
2 |
// Initial the request to mark this this particular post as read
|
3 |
$.post(ajaxurl, { |
4 |
|
5 |
post_id: iPostId |
6 |
|
7 |
}, function (response) { |
8 |
// TODO
|
9 |
});
|
Pada titik ini dalam pembangunan, sumber JavaScript penuh akan terlihat seperti ini:
1 |
|
2 |
(function ($) { |
3 |
$(function () { |
4 |
|
5 |
// If the "I've Read This Container" is on this page, let's setup the event handler
|
6 |
if(1 === $('#ive-read-this-container').length) { |
7 |
|
8 |
// We use the change attribute so that the event handler fires
|
9 |
// whenever the checkbox or its associated label are clicked.
|
10 |
$('input[name="ive-read-this"]').change(function (evt) { |
11 |
|
12 |
// We can retrieve the ID of this post from the <article>'s ID. This will be required
|
13 |
// so that we can mark that the user has read this particular post and we can hide it.
|
14 |
var sArticleId, iPostId; |
15 |
|
16 |
// Get the article ID and split it - the second index is always the post ID in Twenty Eleven
|
17 |
sArticleId = $("article").attr('id'); |
18 |
iPostId = parseInt(sArticleId.split('-')[1]); |
19 |
|
20 |
// Initialise the request to mark this particular post as read
|
21 |
$.post(ajaxurl, { |
22 |
|
23 |
post_id: iPostId |
24 |
|
25 |
}, function (response) { |
26 |
// TODO
|
27 |
});
|
28 |
|
29 |
});
|
30 |
|
31 |
} // end if |
32 |
|
33 |
});
|
34 |
}(jQuery)); |
Bagi Anda yang telah bekerja melalui kode contoh sebagai Anda membaca artikel, Anda akan segera melihat bahwa browser Anda melempar kesalahan konsol:
Exception ReferenceError: ajaxurl tidak didefinisikan
UPS! Dan ini adalah di mana kita perlu untuk memastikan benar termasuk Perpustakaan Ajax WordPress'.
Termasuk Perpustakaan Ajax WordPress' pada Frontend
Untuk melakukan ini, kita akan perlu untuk hook ke action wp_head
. Menambahkan baris kode berikut dalam konstruktor plugin:
1 |
|
2 |
// Include the Ajax library on the front end
|
3 |
add_action( 'wp_head', array( &$this, 'add_ajax_library' ) ); |
Selanjutnya, tambahkan fungsi berikut. Ini adalah apa benar-benar bertanggung jawab untuk memasukan Perpustakaan Ajax:
1 |
|
2 |
/**
|
3 |
* Adds the WordPress Ajax Library to the frontend.
|
4 |
*/
|
5 |
public function add_ajax_library() { |
6 |
|
7 |
$html = '<script type="text/javascript">'; |
8 |
$html .= 'var ajaxurl = "' . admin_url( 'admin-ajax.php' ) . '"'; |
9 |
$html .= '</script>'; |
10 |
|
11 |
echo $html; |
12 |
|
13 |
} // end add_ajax_library |
Sekarang, jika Anda mencoba untuk mengeksekusi kode, Anda seharusnya tidak memiliki masalah. Pada titik ini, kami siap untuk terus berjalan.
Menangani Evebt: menandai posting sebagai telah dibaca
Sekarang bahwa kita punya reqyest yang dikirim ke server, kita dapat menulis kami sisi server event handler. Ini adalah bagaimana handler harus beroperasi:
- Periksa bahwa nilai posting ID masuk diatur dan bahwa itu adalah nilai numerik (ini adalah sangat dasar spoof perlindungan, tapi ia bekerja untuk semua maksud dan tujuan).
- Selanjutnya, Coba perbarui meta pengguna saat ini menggunakan ID dan post ID.
- Jika gagal update, kita akan mengembalikan
-1
; Jika tidak, kita akan mengembalikan1
. Kami akan menangani nilai-nilai ini dalam respon handler di JavaScript.
Pertama, kita akan menambahkan hook dalam konstruktor plugin:
1 |
|
2 |
// Setup the event handler for marking this post as read for the current user
|
3 |
add_action( 'wp_ajax_mark_as_read', array( &$this, 'mark_as_read' ) ); |
Selanjutnya, kami akan benar-benar menerapkan handler:
1 |
|
2 |
/**
|
3 |
* Uses the current user ID and the incoming post ID to mark this post as read
|
4 |
* for the current user.
|
5 |
*
|
6 |
* We store this post's ID in the associated user's meta so that we can hide it
|
7 |
* from displaying in the list later.
|
8 |
*/
|
9 |
public function mark_as_read() { |
10 |
|
11 |
// First, we need to make sure the post ID parameter has been set and that it's a numeric value
|
12 |
if( isset( $_POST['post_id'] ) && is_numeric( $_POST['post_id'] ) ) { |
13 |
|
14 |
// If we fail to update the user meta, respond with -1; otherwise, respond with 1.
|
15 |
echo false == update_user_meta( wp_get_current_user()->ID, $_POST['post_id'], 'ive_read_this' ) ? "-1" : "1"; |
16 |
|
17 |
} // end if |
18 |
|
19 |
die(); |
20 |
|
21 |
} // end mark_as_read |
Untuk itu, mari kita kembali TODO
luar biasa dalam respon fungsi JavaScript yang kita bekerja pada. Berikut adalah script lengkap:
1 |
|
2 |
(function ($) { |
3 |
$(function () { |
4 |
|
5 |
// If the "I've Read This Container" is on this page, let's setup the event handler
|
6 |
if(1 === $('#ive-read-this-container').length) { |
7 |
|
8 |
// We use the change attribute so that the event handler fires
|
9 |
// whenever the checkbox or its associated label are clicked.
|
10 |
$('input[name="ive-read-this"]').change(function (evt) { |
11 |
|
12 |
// We can retrieve the ID of this post from the <article>'s ID. This will be required
|
13 |
// so that we can mark that the user has read this particular post and we can hide it.
|
14 |
var sArticleId, iPostId; |
15 |
|
16 |
// Get the article ID and split it - the second index is always the post ID in Twenty Eleven
|
17 |
sArticleId = $("article").attr('id'); |
18 |
iPostId = parseInt(sArticleId.split('-')[1]); |
19 |
|
20 |
// Initial the request to mark this this particular post as read
|
21 |
$.post(ajaxurl, { |
22 |
|
23 |
action: 'mark_as_read', |
24 |
post_id: iPostId |
25 |
|
26 |
}, function (response) { |
27 |
|
28 |
// If the server returns '1', then we can mark this post as read, so we'll hide the checkbox
|
29 |
// container. Next time the user browses the index, this post won't appear
|
30 |
if (1 === parseInt(response)) { |
31 |
|
32 |
$('#ive-read-this-container').slideUp('fast'); |
33 |
|
34 |
// Otherwise, let's alert the user that there was a problem. In a larger environment, we'd
|
35 |
// want to handle this more gracefully.
|
36 |
} else { |
37 |
|
38 |
alert("There was an error marking this post as read. Please try again."); |
39 |
|
40 |
} // end if/else |
41 |
|
42 |
});
|
43 |
|
44 |
});
|
45 |
|
46 |
} // end if |
47 |
|
48 |
});
|
49 |
}(jQuery)); |
Salah satu perubahan lain
Jika pengguna kebetulan menemukan jalan mereka ke halaman posting individu (seperti yang terkait dengan itu), kita harus memeriksa untuk melihat jika mereka sebelumnya telah ditandai untuk dibaca.
Untuk melakukan ini, kita perlu refactor fungsi add_checkbox
sehingga memeriksa untuk melihat apakah pengguna masuk dan membaca meta pengguna untuk menentukan apakah post sebelumnya telah ditandai sudah dibaca:
1 |
|
2 |
/**
|
3 |
* Adds a checkbox to the end of a post in single view that allows users who are logged in
|
4 |
* to mark their post as read.
|
5 |
*
|
6 |
* @param $content The post content
|
7 |
* @return The post content with or without the added checkbox
|
8 |
*/
|
9 |
public function add_checkbox( $content ) { |
10 |
|
11 |
// We only want to modify the content if the user is logged in
|
12 |
if( is_single() ) { |
13 |
|
14 |
// If the user is logged in...
|
15 |
if( is_user_logged_in() ) { |
16 |
|
17 |
// And if they've previously read this post...
|
18 |
if( 'ive_read_this' == get_user_meta( wp_get_current_user()->ID, get_the_ID(), true ) ) { |
19 |
|
20 |
// Build the element to indicate this post has been read
|
21 |
$html = '<div id="ive-read-this-container">'; |
22 |
$html .= '<strong>'; |
23 |
$html .= __( "I've read this post.", 'ive-read-this' ); |
24 |
$html .= '</strong>'; |
25 |
$html .= '</div><!-- /#ive-read-this-container -->'; |
26 |
|
27 |
// Otherwise, give them the option to mark this post as read
|
28 |
} else { |
29 |
|
30 |
// Build the element that will be used to mark this post as read
|
31 |
$html = '<div id="ive-read-this-container">'; |
32 |
$html .= '<label for="ive-read-this">'; |
33 |
$html .= '<input type="checkbox" name="ive-read-this" id="ive-read-this" value="0" />'; |
34 |
$html .= __( "I've read this post.", 'ive-read-this' ); |
35 |
$html .= '</label>'; |
36 |
$html .= '</div><!-- /#ive-read-this-container -->'; |
37 |
|
38 |
} // end if |
39 |
|
40 |
// Append it to the content
|
41 |
$content .= $html; |
42 |
|
43 |
} // end if |
44 |
|
45 |
} // end if |
46 |
|
47 |
return $content; |
48 |
|
49 |
} // end add_checkbox |
Melihatnya beraksi!
Pada titik ini, Anda sudah punya sebuah plugin bekerja:
- Anda harus dapat menavigasi ke setiap pos
- Jika Anda sudah tidak membacanya, maka Anda harus dapat klik kotak centang dan akan menghilang
- Jika Anda memuat ulang halaman, kemudian Anda akan melihat pemberitahuan bahwa post telah ditandai sebagai telah dibaca.
Tidak buruk, kan?
Tentu saja, selalu ada ruang untuk percobaan Anda sendiri dengan ini. Misalnya, Anda dapat bekerja pada tidak termasuk post ini dari loop utama jika mereka telah ditandai sebagai telah dibaca. Pilihan lain akan menambah classname kustom dan styling kemudian posting untuk menunjukkan bahwa pengguna saat ini telah membacanya.
Akhirnya, ingat bahwa Anda dapat mengambil semua kode sumber secara keseluruhan di GitHub.