आप .pointer( 'open' );
सभी पॉइंट ऑब्जेक्ट्स पर जावास्क्रिप्ट फ़ंक्शन को कॉल कर रहे हैं, इसलिए यह आश्चर्य की बात नहीं है कि सभी पॉइंटर्स एक ही समय पर दिखाई देते हैं ...
उस ने कहा, मुझे समझ में नहीं आता है कि आप सभी पॉइंटर्स (यहां तक कि गैर-सक्रिय वाले) को क्यों लौटाते हैं custom_admin_pointers()
और फिर जाँचने के लिए एक अतिरिक्त फ़ंक्शन if ( $array['active'] ) {
जोड़ते हैं कि क्या जावास्क्रिप्ट पॉइंटर जोड़ने के लिए चुनने के लिए कुछ सक्रिय पॉइंटर्स और पॉइंटर्स लूप ( ) के अंदर एक चेक है या नहीं। क्या सिर्फ़ सिर्फ़ सक्रिय बिंदुओं को लौटाना सरल नहीं है?
इसके अलावा, आप सभी व्यवस्थापक पृष्ठों पर उस जावास्क्रिप्ट को जोड़ रहे हैं, बहुत अधिक नहीं है? यह भी विचार करें कि "# सेव-पोस्ट" जैसे कुछ तत्व केवल नए पोस्ट पेज पर उपलब्ध हैं, इसलिए केवल नए पॉट पेज में पॉइंटर्स जोड़ना बेहतर नहीं है?
अंत में, उस जावास्क्रिप्ट को PHP के साथ कैसे गड़बड़ किया गया, मुझे लगता है कि आपको wp_localize_script
जावास्क्रिप्ट को डेटा पास करने के लिए उपयोग करने पर विचार करना चाहिए ।
योजना:
- PHP में पॉइंटर्स की परिभाषाओं को एक अलग फ़ाइल में ले जाएं, इस तरह से इसे संपादित करना आसान है और PHP कोड से मार्कअप को भी हटा दें, सब कुछ अधिक पठनीय और मुख्य है।
- पॉइंटर्स कॉन्फ़िगरेशन में एक गुण जोड़ें "जहां" जिसका उपयोग उस सेट में किया जाएगा जिसमें व्यवस्थापक पृष्ठ पॉपअप दिखाई दे::
post-new.php
, index.php
...
- एक वर्ग लिखें जो लोडिंग, पार्सिंग और पॉइंटर्स जानकारी को फ़िल्टर करने का काम करेगा
- कुछ js अच्छाई लिखें जो हमें "अगला" बटन डिफ़ॉल्ट "निकालें" को बदलने में मदद करेगा
# 4 कर सकते हैं (शायद) आसानी से किया सूचक अच्छी तरह से जानते हुए भी प्लगइन है, लेकिन यह मेरे मामले में नहीं है। इसलिए मैं परिणाम प्राप्त करने के लिए सामान्य jQuery कोड का उपयोग करूंगा, अगर कोई मेरे कोड में सुधार कर सकता है जिसकी मैं सराहना करूंगा।
संपादित करें
मैंने कोड (मुख्य रूप से js) को संपादित किया क्योंकि वहाँ अलग-अलग चीजें हैं जिन पर मैंने विचार नहीं किया था: कुछ संकेत एक ही लंगर में जोड़े जा सकते हैं, या एक ही संकेत गैर-मौजूदा या गैर-दृश्यमान एंकर में जोड़े जा सकते हैं। पिछले कोड में काम नहीं करने वाले सभी मामलों में, नया संस्करण उस मुद्दे को अच्छी तरह से संबोधित करता है।
मैंने उन सभी कोड के साथ एक Gist सेटअप भी किया है जिसका मैं परीक्षण करता था।
आइए अंक # 1 और # 2 के साथ शुरू करें : नाम से एक फ़ाइल बनाएं pointers.php
और वहां लिखें:
<?php
$pointers = array();
$pointers['new-items'] = array(
'title' => sprintf( '<h3>%s</h3>', esc_html__( 'Add New Item' ) ),
'content' => sprintf( '<p>%s</p>', esc_html__( 'Easily add a new post..' ) ),
'anchor_id' => '#wp-admin-bar-new-content',
'edge' => 'top',
'align' => 'left',
'where' => array( 'index.php', 'post-new.php' ) // <-- Please note this
);
$pointers['story_cover_help'] = array(
'title' => sprintf( '<h3>%s</h3>', esc_html__( 'Another info' ) ),
'content' => sprintf( '<p>%s</p>', esc_html__( 'Lore ipsum....' ) ),
'anchor_id' => '#save-post',
'edge' => 'top',
'align' => 'right',
'where' => array( 'post-new.php' ) // <-- Please note this
);
// more pointers here...
return $pointers;
सभी संकेत विन्यास यहाँ है। जब आपको कुछ बदलने की आवश्यकता होती है, तो बस इस फ़ाइल को खोलें और इसे संपादित करें।
"जहां" संपत्ति पर ध्यान दें जो पृष्ठों की एक सरणी है जहां सूचक उपलब्ध होना चाहिए।
यदि आप किसी प्लगइन द्वारा जनरेट किए गए पृष्ठ में पॉइंटर्स प्रदर्शित करना चाहते हैं, तो नीचे उल्लिखित इस लाइन को देखें public function filter( $page ) {
और die($page);
तुरंत इसे नीचे जोड़ें । फिर संबंधित प्लगइन पेज खोलें और where
संपत्ति में उस स्ट्रिंग का उपयोग करें ।
ठीक है, अब बिंदु # 3 ।
कक्षा लिखने से पहले मैं केवल एक इंटरफ़ेस कोड करना चाहता हूं: वहां मैं टिप्पणियां डालूंगा ताकि आप बेहतर समझ सकें कि कक्षा क्या करेगी।
<?php
interface PointersManagerInterface {
/**
* Load pointers from file and setup id with prefix and version.
* Cast pointers to objects.
*/
public function parse();
/**
* Remove from parse pointers dismissed ones and pointers
* that should not be shown on given page
*
* @param string $page Current admin page file
*/
public function filter( $page );
}
मुझे लगता है कि बहुत स्पष्ट होना चाहिए। अब क्लास लिखते हैं, इसमें इंटरफ़ेस और कंस्ट्रक्टर के 2 तरीके होंगे।
<?php namespace GM;
class PointersManager implements PointersManagerInterface {
private $pfile;
private $version;
private $prefix;
private $pointers = array();
public function __construct( $file, $version, $prefix ) {
$this->pfile = file_exists( $file ) ? $file : FALSE;
$this->version = str_replace( '.', '_', $version );
$this->prefix = $prefix;
}
public function parse() {
if ( empty( $this->pfile ) ) return;
$pointers = (array) require_once $this->pfile;
if ( empty($pointers) ) return;
foreach ( $pointers as $i => $pointer ) {
$pointer['id'] = "{$this->prefix}{$this->version}_{$i}";
$this->pointers[$pointer['id']] = (object) $pointer;
}
}
public function filter( $page ) {
if ( empty( $this->pointers ) ) return array();
$uid = get_current_user_id();
$no = explode( ',', (string) get_user_meta( $uid, 'dismissed_wp_pointers', TRUE ) );
$active_ids = array_diff( array_keys( $this->pointers ), $no );
$good = array();
foreach( $this->pointers as $i => $pointer ) {
if (
in_array( $i, $active_ids, TRUE ) // is active
&& isset( $pointer->where ) // has where
&& in_array( $page, (array) $pointer->where, TRUE ) // current page is in where
) {
$good[] = $pointer;
}
}
$count = count( $good );
if ( $good === 0 ) return array();
foreach( array_values( $good ) as $i => $pointer ) {
$good[$i]->next = $i+1 < $count ? $good[$i+1]->id : '';
}
return $good;
}
}
कोड बहुत सरल है, और वास्तव में इंटरफ़ेस क्या उम्मीद करता है।
हालाँकि, कक्षा अपने आप कुछ नहीं करती है, हमें एक हुक की आवश्यकता होती है जहाँ कक्षा nad को तुरंत शुरू करने के लिए 2 विधियाँ उचित तर्क प्रस्तुत करती हैं।
'admin_enqueue_scripts'
हमारे क्षेत्र के लिए एकदम सही है: वहाँ हम वर्तमान व्यवस्थापक पृष्ठ के लिए उपयोग होगा और हम भी कतारबद्ध स्क्रिप्ट और शैलियों की जरूरत कर सकते हैं।
add_action( 'admin_enqueue_scripts', function( $page ) {
$file = plugin_dir_path( __FILE__ ) . 'pointers.php';
// Arguments: pointers php file, version (dots will be replaced), prefix
$manager = new PointersManager( $file, '5.0', 'custom_admin_pointers' );
$manager->parse();
$pointers = $manager->filter( $page );
if ( empty( $pointers ) ) { // nothing to do if no pointers pass the filter
return;
}
wp_enqueue_style( 'wp-pointer' );
$js_url = plugins_url( 'pointers.js', __FILE__ );
wp_enqueue_script( 'custom_admin_pointers', $js_url, array('wp-pointer'), NULL, TRUE );
// data to pass to javascript
$data = array(
'next_label' => __( 'Next' ),
'close_label' => __('Close'),
'pointers' => $pointers
);
wp_localize_script( 'custom_admin_pointers', 'MyAdminPointers', $data );
} );
कुछ खास नहीं: सिर्फ पॉइंटर्स डेटा प्राप्त करने के लिए क्लास का उपयोग करना और अगर कुछ पॉइंटर्स फिल्टर एनक्यू स्टाइल और स्क्रिप्ट पास करना। फिर बटन के लिए स्थानीयकृत "नेक्स्ट" लेबल के साथ स्क्रिप्ट को पॉइंटर्स डेटा पास करें।
ठीक है, अब "सबसे कठिन" हिस्सा: जेएस। फिर से मैं यह बताना चाहता हूं कि मुझे पता नहीं है कि पॉइंटर प्लगइन वर्डप्रेस का उपयोग करता है, इसलिए मैं अपने कोड में जो करता हूं वह बेहतर हो सकता है यदि कोई इसे जानता है, हालांकि मेरा कोड अपना काम करता है और मूल रूप से बोलता है- यह इतना बुरा नहीं है।
( function($, MAP) {
$(document).on( 'MyAdminPointers.setup_done', function( e, data ) {
e.stopImmediatePropagation();
MAP.setPlugin( data ); // open first popup
} );
$(document).on( 'MyAdminPointers.current_ready', function( e ) {
e.stopImmediatePropagation();
MAP.openPointer(); // open a popup
} );
MAP.js_pointers = {}; // contain js-parsed pointer objects
MAP.first_pointer = false; // contain first pointer anchor jQuery object
MAP.current_pointer = false; // contain current pointer jQuery object
MAP.last_pointer = false; // contain last pointer jQuery object
MAP.visible_pointers = []; // contain ids of pointers whose anchors are visible
MAP.hasNext = function( data ) { // check if a given pointer has valid next property
return typeof data.next === 'string'
&& data.next !== ''
&& typeof MAP.js_pointers[data.next].data !== 'undefined'
&& typeof MAP.js_pointers[data.next].data.id === 'string';
};
MAP.isVisible = function( data ) { // check if anchor for given pointer is visible
return $.inArray( data.id, MAP.visible_pointers ) !== -1;
};
// given a pointer object, return its the anchor jQuery object if available
// otherwise return first available, lookin at next property of subsequent pointers
MAP.getPointerData = function( data ) {
var $target = $( data.anchor_id );
if ( $.inArray(data.id, MAP.visible_pointers) !== -1 ) {
return { target: $target, data: data };
}
$target = false;
while( MAP.hasNext( data ) && ! MAP.isVisible( data ) ) {
data = MAP.js_pointers[data.next].data;
if ( MAP.isVisible( data ) ) {
$target = $(data.anchor_id);
}
}
return MAP.isVisible( data )
? { target: $target, data: data }
: { target: false, data: false };
};
// take pointer data and setup pointer plugin for anchor element
MAP.setPlugin = function( data ) {
if ( typeof MAP.last_pointer === 'object') {
MAP.last_pointer.pointer('destroy');
MAP.last_pointer = false;
}
MAP.current_pointer = false;
var pointer_data = MAP.getPointerData( data );
if ( ! pointer_data.target || ! pointer_data.data ) {
return;
}
$target = pointer_data.target;
data = pointer_data.data;
$pointer = $target.pointer({
content: data.title + data.content,
position: { edge: data.edge, align: data.align },
close: function() {
// open next pointer if it exists
if ( MAP.hasNext( data ) ) {
MAP.setPlugin( MAP.js_pointers[data.next].data );
}
$.post( ajaxurl, { pointer: data.id, action: 'dismiss-wp-pointer' } );
}
});
MAP.current_pointer = { pointer: $pointer, data: data };
$(document).trigger( 'MyAdminPointers.current_ready' );
};
// scroll the page to current pointer then open it
MAP.openPointer = function() {
var $pointer = MAP.current_pointer.pointer;
if ( ! typeof $pointer === 'object' ) {
return;
}
$('html, body').animate({ // scroll page to pointer
scrollTop: $pointer.offset().top - 30
}, 300, function() { // when scroll complete
MAP.last_pointer = $pointer;
var $widget = $pointer.pointer('widget');
MAP.setNext( $widget, MAP.current_pointer.data );
$pointer.pointer( 'open' ); // open
});
};
// if there is a next pointer set button label to "Next", to "Close" otherwise
MAP.setNext = function( $widget, data ) {
if ( typeof $widget === 'object' ) {
var $buttons = $widget.find('.wp-pointer-buttons').eq(0);
var $close = $buttons.find('a.close').eq(0);
$button = $close.clone(true, true).removeClass('close');
$buttons.find('a.close').remove();
$button.addClass('button').addClass('button-primary');
has_next = false;
if ( MAP.hasNext( data ) ) {
has_next_data = MAP.getPointerData(MAP.js_pointers[data.next].data);
has_next = has_next_data.target && has_next_data.data;
}
var label = has_next ? MAP.next_label : MAP.close_label;
$button.html(label).appendTo($buttons);
}
};
$(MAP.pointers).each(function(index, pointer) { // loop pointers data
if( ! $().pointer ) return; // do nothing if pointer plugin isn't available
MAP.js_pointers[pointer.id] = { data: pointer };
var $target = $(pointer.anchor_id);
if ( $target.length && $target.is(':visible') ) { // anchor exists and is visible?
MAP.visible_pointers.push(pointer.id);
if ( ! MAP.first_pointer ) {
MAP.first_pointer = pointer;
}
}
if ( index === ( MAP.pointers.length - 1 ) && MAP.first_pointer ) {
$(document).trigger( 'MyAdminPointers.setup_done', MAP.first_pointer );
}
});
} )(jQuery, MyAdminPointers); // MyAdminPointers is passed by `wp_localize_script`
टिप्पणियों की मदद से कोड बहुत स्पष्ट होना चाहिए, कम से कम, मुझे उम्मीद है।
ठीक है, हम कर रहे हैं हमारा PHP सरल और बेहतर रूप से व्यवस्थित है, हमारी जावास्क्रिप्ट अधिक पठनीय है, संकेत संपादित करना आसान है और, अधिक महत्वपूर्ण, सब कुछ काम करता है।