web-dev-qa-db-ja.com

ウィジェットからプラグイン内の関数に値を渡す

私は多くのウィジェットで構築されているプラ​​グインを持っています。ウィジェットのバンドル。各ウィジェットは独自のカスタムCSSコードを作成します。

15種類の異なるインラインCSSコードを表示するような面倒なソースコードを用意する代わりに、各ウィジェットからカスタム生成されたCSSコードをWordPress AJAXを介して作成したメインのカスタムCSSファイルに渡したいと思います。

これを可能にするために設定した機能を表示します。

AJAX作成されたCSSファイル

以下のCSSファイルはWordPress AJAXを介して作成されています。それは私がファイルにカスタムCSSステートメントを置くことを可能にします。生成された余分なCSSをウィジェットからこの関数(ファイル)に渡すことを望んでいるフィルタも含まれています。

/**
 * Echo the CSS for the custom widgets style
 */
public function advanced_widget_pack_css() {
    if(empty($_GET['action']) || $_GET['action'] != 'advanced_widget_pack_gen_css') return;
    if(!isset($_GET['ver'])) return;

    $css_text = '';

    /* ============================= */
    /* Archives Widget               */
    /* ============================= */
    $css_text .= ".awp_archives_colour { color:".awp_option('awp_archives_dropdown_inst_colour')." !important }\n"; 

    /**
     * Filter for any incoming CSS
     */
    $css_text = apply_filters('advanced_widget_pack_css', $css_text);

    header("Content-type: text/css");
    echo $css_text;
    exit();
}

カスタム生成されたCSSコードを持つウィジェットクラスの1つ

以下のコードは、プラグイン内で使用されている多くのウィジェットのうちの1つのスニペットです。ウィジェットはカスタムCSSコードを作成し、それを変数$sc_cssに格納します。ここからやりたいのは、変数$sc_cssの内容を渡すか、先ほど作成した関数advanced_widget_pack_css()に内容を追加することです。

class Advanced_Widget_Pack_Widget_Archives extends WP_Widget {

    public function __construct(){
        // This filter hooks the custom genrated css code to the advanced_widget_pack_css function
        add_filter('advanced_widget_pack_css', array(&$this,'awp_pass_css_code'));
    }

    public function form($instance) {}

    public function widget($args, $instance){

        extract($args);

        // All the widget code is contained here....

        // Styling for the shortcode
        if($is_awp_sc == 'true'){

            /* Generate unique id if shortcode - used for styling */
            $sc_id = mt_Rand(1, 100000);

            $sc_css =  ".awp_archive_widget_sc".$sc_id." { border:".$awp_archives_border_width.' '.$awp_archives_border_style.' '.$awp_archives_border_color." !important }\n";
            $sc_css .= $awp_archives_border_radius == 'round' ? '.awp_archive_widget_sc'.$sc_id.' { -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px }' : ''.''." \n";

            $sc_css .= ".awp_archive_widget_sc".$sc_id." li a, .awp_archive_widget_sc".$sc_id." li { font-size:".$awp_archives_font_size." !important }\n";
            $sc_css .= ".awp_archive_widget_sc".$sc_id." li a { color:".$awp_archives_link_std." !important }\n";
            $sc_css .= ".awp_archive_widget_sc".$sc_id." li a:hover { color:".$awp_archives_link_hover." !important }\n";

            // This should pass the variable
            echo $this->awp_pass_css_code($sc_css);
        }

        // The widget code gets outputted here
    }

    // This function is created to pass the content of the variable $sc_css to the advanced_widget_pack_css function
    function awp_pass_css_code( $sc_css ) {
        return $sc_css;
    }
}

問題

私はこれを実現するために、ウィジェット内の関数に$sc_css変数の内容を渡してから、WordPressフィルタを通してそれを関数advanced_widget_pack_css()にフックしました。

発生する問題は、それらをAJAX生成スタイルシートに渡すと、変数の内容が常に空白になることです。

1
Jason

まず第一に私はあなたのコードが機能しない理由を言うことができます。

カスタムCSSは、ウィジェットが表示された瞬間にWordPressによって呼び出されるwidget関数内に作成されます。

advanced_widget_pack_css()関数を呼び出すajaxリクエストを送信する準備が整いました。しかし、すべてのAjaxリクエストは、唯一のスコープが関数を実行しているというまったく新しいHTTPリクエストであり、ウィジェットを埋め込むことはできません。

このため、ajaxを介した新しいリクエストではウィジェットクラスのwidget()メソッドが呼び出されることはなく、もちろんCSSは追加されません。

それを言って、あなたがしていることのために1分を考えてください。

ワークフローが機能すると仮定して、ユーザーが有効になっているjsがない場合は失敗します。 jsが有効になっていても、ページはカスタムCSSでロードされます。これはajaxリクエストでロードする必要があります(そしてWordPressのAjaxはそれほど高速ではありません...)。

  • いいえjsもcssもない場合
  • jsページがCSSなしでロードされたとしても、あなたは2秒以上の間スタイルの整っていないウィジェットを持っています
  • ブラウザはCSSのキャッシュを許可されていません

そのため、あなたのコードはうまくいきません(なぜ私はyopuを説明しました)が、うまくいく方法を見つけたとしてもそれは素晴らしい解決策ではありません。

解決策は何ですか?

まず最初にウィジェットの中でカスタムCSSを生成する関数を分離します。

その後、widget()メソッドではなくupdateメソッドで関数を呼び出す必要があります。このようにして、ウィジェットが更新されるたびにCSSが生成され、新しく生成されたCSSを保存してCSSファイルに保存することができます

このフォルダはWPから書き込み可能であることが確実であるため、グッドプラクティスとして、uploadsフォルダにこのファイルを保存することをお勧めします。

擬似コード

class Advanced_Widget_Pack_Widget_Archives extends WP_Widget {

   function generate_css( $instance ) {
     // some code here to generate css from instance arguments...
     return $sc_css;
   }

   function update( $new_instance, $old_instance ) {
     // some code here to update the widget instance...
     $css = $this->generate_css( $new_instance );
     $upload_dir = wp_upload_dir();
     $path = $upload_dir['basedir'] . '/myplugin/myplugin-customwidget.css';
     if ( ! file_exists($upload_dir['basedir'] . '/myplugin') )
       mkdir($upload_dir['basedir'] . '/myplugin');
     file_put_contents($path, $css);
   }

}

その後、WordPressの標準的な方法で作成したファイルをエンキューできます。

このメソッドに代わるものはwidget()メソッドでcssを生成し(すでに行っているように)、マークアップでインラインスタイルとして出力することです。

1
gmazzap

あなたのための素早い解決策は、シリアル化された配列のすべてのあなたの生成されたcssデータをWordPressデータベースに格納して、それを取得する/ get_option/set_optionでそれを設定することです

0
Nicü