আপনি .pointer( 'open' );
সমস্ত পয়েন্টার অবজেক্টগুলিতে জাভাস্ক্রিপ্ট ফাংশনটি কল করছেন , তাই অবাক হওয়ার কিছু নেই যে সমস্ত পয়েন্টার একই সময়ে উপস্থিত হয় ...
এটি বলেছিল, আমি বুঝতে পারি না যে আপনি কেন সমস্ত পয়েন্টার (এমনকি অ-অ্যাক্টিভ वाले) থেকে ফিরিয়ে দেন custom_admin_pointers()
এবং তারপরে if ( $array['active'] ) {
জাভাস্ক্রিপ্ট পয়েন্টার যুক্ত করার জন্য কিছু সক্রিয় পয়েন্টার এবং পয়েন্টার লুপের ভিতরে একটি চেক রয়েছে কিনা তা পরীক্ষা করার জন্য একটি অতিরিক্ত ফাংশন যুক্ত করেন? অথবা না. সহজ কি কেবলমাত্র সক্রিয় পয়েন্টারগুলি ফিরছে না?
তাছাড়া, আপনি সমস্ত অ্যাডমিন পৃষ্ঠায় জাভাস্ক্রিপ্ট যুক্ত করছেন, খুব বেশি না? এছাড়াও বিবেচনা করুন যে "# সেভ-পোস্ট" এর মতো কিছু উপাদানগুলি কেবল নতুন পোস্ট পৃষ্ঠায় পাওয়া যায়, তবে কেবলমাত্র নতুন পট পৃষ্ঠায় পয়েন্টার যুক্ত করা ভাল নয়?
পরিশেষে, এই জাভাস্ক্রিপ্টটি পিএইচপি এর সাথে মিশে গেছে এমন কতটা অগোছালো, আমি মনে করি আপনার wp_localize_script
জাভাস্ক্রিপ্টে ডেটা পাস করার জন্য ব্যবহার করা উচিত ।
পরিকল্পনা:
- পিএইচপি-র পয়েন্টার সংজ্ঞাগুলি একটি পৃথক ফাইলে সরান, এইভাবে সম্পাদনা করা সহজ এবং পিএইচপি কোড থেকে মার্কআপ অপসারণ করা সহজ, সবকিছুই আরও পঠনযোগ্য এবং মূল লক্ষ্যযোগ্য
- পয়েন্টার একটি সম্পত্তি "কোথায়" সেট যা অ্যাডমিন পৃষ্ঠা থেকে একটি পপআপ প্রদর্শিত হওয়া উচিত করতে ব্যবহার করা হবে যোগ কনফিগারেশন:
post-new.php
, index.php
...
- এমন একটি শ্রেণি লিখুন যা লোডিং, পার্সিং এবং পয়েন্টারগুলির তথ্যের ফিল্টারিং পরিচালনা করবে
- কিছু জেএস নেকি লিখুন যা আমাদের ডিফল্ট "সরান" বোতামটি "পরবর্তী" তে পরিবর্তন করতে সহায়তা করবে
# 4 করতে পারেন (সম্ভবত) সহজে সম্পন্ন পয়েন্টার ভাল প্লাগ ইন বুদ্ধিমান, কিন্তু এটা আমার ক্ষেত্রে নয়। সুতরাং আমি ফলাফলটি পেতে সাধারণ jQuery কোড ব্যবহার করব, যদি কেউ আমার কোডটি উন্নত করতে পারে তবে আমি প্রশংসা করব।
সম্পাদন করা
আমি কোডটি সম্পাদনা করেছি (প্রধানত জেএস) কারণ বিভিন্ন জিনিস যা আমি বিবেচনা করি নি: কিছু পয়েন্টার একই অ্যাঙ্কারে যুক্ত হতে পারে, বা একই পয়েন্টারগুলি অ-বিদ্যমান বা অ-দৃশ্যমান অ্যাঙ্করগুলিতে যুক্ত করা যেতে পারে। আগের ক্ষেত্রে কোডটি কাজ করত না, নতুন সংস্করণটি দুর্দান্তভাবে সমাধান করেছে বলে মনে হচ্ছে।
আমি পরীক্ষার জন্য ব্যবহৃত সমস্ত কোড সহ একটি গিস্ট সেটআপ করেছি ।
আসুন পয়েন্ট # 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;
}
}
কোড খুব সহজ, এবং ইন্টারফেসটি যা প্রত্যাশা করে ঠিক তা করে।
যাইহোক, ক্লাসটি নিজে থেকে কিছুই করে না, আমাদের এমন একটি হুক দরকার যেখানে ক্লাসের ন্যাডটি ইনস্ট্যান্ট করতে উপযুক্ত যুক্তিগুলি পাস করার 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`
মন্তব্যের সাহায্যে কোডটি বেশ পরিষ্কার হওয়া উচিত, কমপক্ষে, আমিও আশা করি।
ঠিক আছে আমরা হয়ে গেলাম। আমাদের পিএইচপি সহজ এবং আরও সুগঠিত, আমাদের জাভাস্ক্রিপ্ট আরও পাঠযোগ্য, পয়েন্টারগুলি সম্পাদনা করা সহজ এবং আরও গুরুত্বপূর্ণ, সব কিছু কাজ করে।