Advertisement
  1. Code
  2. WordPress
  3. Plugin Development

Primer pada Ajax di WordPress Frontend: benar-benar melakukannya

Scroll to top
Read Time: 15 min
This post is part of a series called A Primer on Ajax in the WordPress Frontend.
A Primer on Ajax in the WordPress Frontend: Understanding the Process

() 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 mengembalikan 1. 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( &amp;$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.


Bacaan terkait

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.