Σύγκριση προϊόντων στο WordPress

Φαντάζομαι όλοι έχετε δει αυτό το feature σε διάφορα sites. Αν όχι, ρίξτε μια ματιά στη σελίδα σύγκρισης προϊόντων του Multirama (τυχαία επιλεγμένη). Επιλέξτε κάποια από τα προϊόντα και απλά πατήστε σύγκριση. Βλέπετε τα προϊόντα σε σειρά ώστε να μπορείτε να συγκρίνετε τιμές, features κλπ.

Ας δούμε πως μπορούμε να φτιάξουμε κάτι παρόμοιο στο WordPress.

Θα μπορούσαμε να φτιάξουμε ένα custom post type το οποίο θα ονομάζαμε products αλλά για να κρατήσουμε τα πράγματα απλά, θα χρησιμοποιήσουμε το default content type το οποίο ακούει στο όνομα Posts.

Αν θέλετε μπορείτε παράλληλα να ανοίξετε το WordPress που έχετε εγκατεστημένο τοπικά ή σε κάποιο test server και να παίξετε. Για να δούμε.

1. Φτιάχνω μερικά “προϊόντα”, στην ουσία posts τα οποία βάζω σε μια κατηγορία που ονομάζω “Products”.

2. Φτιάχνω ένα custom page template με όνομα template-products.php, δημιουργώ μια καινούργια σελίδα, κάνω assign το template που μόλις έφτιαξα και εκεί εμφανίζω τα προϊόντα μου κάπως έτσι:

<?php
/**
 * Template Name: Products
 */

get_header(); ?>

		<div id="container" class="one-column">
			<div id="content" role="main">
			<form method="get" action="http://localhost/wordpress/compare-products/">
			<?php
				 query_posts('cat=19');
				 while (have_posts() ) : the_post(); ?>
					<div class="product">
						<input type="checkbox" name="productIDs&#91;&#93;" value="<?php the_ID(); ?>" />
						<h2><?php the_title(); ?></h2>
						<p><?php the_content(); ?></p>
					</div>
				<?php endwhile; ?>
			</div><!-- #content -->
			<p><input type="submit" id="submit" value="Compare products" /></p>
			</form>
		</div><!-- #container -->

<?php get_footer(); ?>

Όπως βλέπουμε πρόκειται για ένα απλό template με κάποιες μικρές διαφορές σε σχέση με κάποιο τυπικό page template. Για αρχή βλέπουμε ότι το loop είναι κλεισμένο μέσα σε ένα form tag. Επίσης, μέσα στο loop όπου εμφανίζουμε τον τίτλο του προϊόντος και το περιεχόμενο έχουμε ένα checkbox. Το checkbox αυτό θα εμφανιστεί δίπλα σε κάθε προϊόν ώστε να μπορεί ο χρήστης να επιλέξει ποιά προϊόντα θέλει να συγκρίνει. Βλέπουμε πως έχουμε δώσει ένα name=productIDs[] στο checkbox και σαν value περνάμε το μοναδικό για κάθε προϊόν, post_ID. Άρα πλέον μπορούμε, αφού επιλέξουμε κάποια προϊόντα, να πατήσουμε το “Compare products” και να μεταφερθούμε στη σελίδα σύγκρισης. Την οποία ακόμα δεν έχουμε φτιάξει και πριν την κατασκευή της πρέπει να διευκρινήσουμε κάποια πράγματα.

Πατώντας “Compare products” ξέρω πως θα μεταφερθώ στο URL http://localhost/wordpress/complate-products/ γιατί έτσι έχω δηλώσει στο action του form. Πηγαίνοντας όμως εκεί, στο URL πλέον θα υπάρχουν και οι τιμές των checkboxes που έχω επιλέξει με την εξής μορφή (λόγω GET):

http://localhost/wordpress/compare-products/?productIDs[0]=506&productIDs[1]=504

Στο παραπάνω παράδειγμα έχω επιλέξει 2 προϊόντα προς σύγκριση με post_ID 506 & 504 αντίστοιχα. Φαντάζομαι πως έχετε ήδη καταλάβει τι πάω να κάνω. Θα περάσω αυτές τις 2 τιμές σε ένα καινούργιο template. Περνώντας αυτές τις τιμές σαν array σε ένα νέο query μέσω του WP_Query θα εμφανίσω μόνο τα posts με τα συγκεκριμένα post_ID. Έτσι ακριβώς, αλλά έχουμε ένα μικρό πρόβλημα. Το πρόβλημα είναι πως το WordPress ότι δεν γνωρίζει στο URL απλά το απωθεί. Δε του δίνει σημασία. Το γράφει ρε παιδί μου, πως το λένε. Κάπως λοιπόν πρέπει να πούμε στο WordPress ότι θέλουμε να μας κάνει τη χάρη και να μας αφήσει να περάσουμε τις συγκεκριμένες τιμές. Πως; A filter hook που ακούει στο όνομα query_vars. Δείτε περισσότερες πληροφορίες σχετικά στο αντίστοιχο section του Codex.

Ανοίγουμε λοιπόν το functions.php στο theme μας (ή αν θέλετε κάντε το plugin, ώστε σε πιθανή αλλαγή του theme, η λειτουργικότητα να συνεχίσει να υπάρχει):

add_filter('query_vars', 'parameter_queryvars' );
function parameter_queryvars( $qvars )
{
	$qvars[] = 'productIDs';
	return $qvars;
}

Είμαστε έτοιμοι. Το WordPress γνωρίζει την ύπαρξη της μεταβλητής productIDs και θα μας αφήσει να περάσουμε τις τιμές της στο επόμενο template το οποίο δεν είναι άλλο από το compare-products. Φτιάχνουμε λοιπόν ένα δεύτερο αρχείο με όνομα template-compare.php με τον παρακάτω κώδικα:

<?php
/**
 * Template Name: Compare products
 */

get_header(); ?>

		<div id="container" class="one-column">
			<div id="content" role="main">
			<?php
				 $products_to_compare 	= array();
				 $products_to_compare 	= get_query_var('productIDs');
				 $products_to_compare 	= array_map('intval', $products_to_compare);
				 $products_query 		= new WP_Query(array('post__in' => $products_to_compare));
				 while ($products_query->have_posts() ) : $products_query->the_post(); ?>
					<div class="product">
						<h2><?php the_title(); ?></h2>
						<p><?php the_content(); ?></p>
					</div>
				<?php endwhile; ?>

			</div><!-- #content -->
		</div><!-- #container -->

<?php get_footer(); ?>

Φτιάχνουμε μια νέα σελίδα (Pages -> Add new) και της ορίζουμε σαν template το “Compare products” template που μόλις φτιάξαμε. Για να δούμε όμως τι ακριβώς συμβαίνει σε αυτό το template. Βασικά όλη η δουλειά γίνεται στις 4 πρώτες γραμμές PHP.

$products_to_compare 	= array();
$products_to_compare 	= get_query_var('productIDs');
$products_to_compare 	= array_map('intval', $products_to_compare);
$products_query 		= new WP_Query(array('post__in' => $products_to_compare))

Τι κάνουμε;

  1. Δημιουργούμε ένα νέο array.
  2. Μέσα σε αυτό το array πλέον αποθηκεύουμε τις τιμές που υπάρχουν στη μεταβλητή productIDS που περάσαμε από το URL.
  3. Α bit of security. Οι τιμές που έρχονται από το URL πρέπει να είναι ακέραιοι (intval).
  4. Δημιουργούμε το δικό μας query όπου λέμε να μας εμφανίσει στο loop μόνο όσα posts βρίσκονται μέσα στο array που δημιουργήσαμε.

Και έτσι φτιάξαμε το δικό μας σύστημα σύγκρισης προϊόντων στην ουσία με.. 4 γραμμές κώδικα. Easy eh;

Πιθανές βελτιώσεις

  1. Α bit of JS στο πρώτο template αν θέλουμε να περιορίσουμε τα προϊόντα προς επιλογή.
  2. Σε περίπτωση που η JS είναι off, έναν έλεγχο στο 2ο template για το αν έχουν επιλεχθεί προϊόντα και αν όχι να εμφανίσουμε ένα μήνυμα λάθους.

Για περισσότερες πληροφορίες σχετικά με το WP_Query, δείτε την αντίστοιχη σελίδα στο Codex.

5 comments

  1. Εύγε! Μόλις ανελαβα ένα μεγαλούτσικο project που ένα από τα features είναι feature comparison. Μόλις με γλίτωσες από αρκετή δουλειά… 🙂

  2. Tsiger γεια!

    Δοκίμασα να φτιάξω ένα product comparison περί τις οδηγίες σου αλλά το WP μου βγάζει αυτό το error:

    Warning: rawurlencode() expects parameter 1 to be string, array given in /nfs/c08/h02/mnt/116229/domains/sandbox.pixelplay.gr/html/spinmedia/wp-includes/canonical.php on line 283

    Έχεις ιδέα τι μπορεί να σημαίνει αυτό;

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *