web-dev-qa-db-ja.com

動的JavaScript/CSSを生成するためのソリューション

現在のコンテキストに依存するJavaScriptまたはCSSコードを生成する必要があるとしましょう。

たとえば、ホームページに送信時にajaxリクエストを発行するフォームがあり、単一ページに別のフォームがあります。 CSSの場合は、ユーザーが独自のレイアウトを作成したり、色を変更したりできるテーマを作成します。

私がこれまでに見た解決策:

  1. ドキュメントのヘッドセクションにコードを含める(またはJSの場合は最後に)

  2. 次のように、コードを出力する特別な要求をします。 site.com?get_assets。 WPは2回ロードされるため、これは時間がかかります。

  3. 一時ファイルに一定期間保存し、そこからロードします。公共のテーマやプラグインにはあまり信頼できません。

  4. Javascriptのみ - 毎回ロードされる通常のファイルに入れることで静的にします。この場合、あなたはあなたのコードがどんな状況にも対処するようにしなければならないでしょう

あなたは他人を知っていますか?どちらに行きますか。

14
onetrickpony

渡す必要があるパラメータの種類に応じて、1つの追加オプションがあります。それを呼び出しましょう(2a)。 text/cssではなく動的に生成されたtext/javascriptまたはtext/htmlを出力するPHPスクリプトを作成し、それらに必要なデータをWordPressをロードするのではなくGETパラメータを使用して提供することもできます。もちろん、これは比較的少数の比較的コンパクトなパラメータを渡す必要がある場合にのみ機能します。たとえば、投稿のURLやファイルのディレクトリなどを渡す必要があるとしたら、次のようにすることができます。

Header.php:

 <script type="text/javascript" src="<?php print get_stylesheet_directory_uri(); 
 ?>/fancy-js.php?foo=bar&amp;url=<?php print urlencode(get_permalink($post->ID)); ?>"></script>

空想 - js.php:

 <?php
 header("Content-type: text/javascript");
 ?>
 foo = <?php print json_encode($_GET['foo']); ?>;
 url = <?php print json_encode($_GET['url']); ?>;

等.

しかし、これはあなたがGETパラメータで直接渡されたデータへのアクセスを許可するだけです。そしてそれはあなたが渡す必要があるものの数が比較的少なく、そしてそれらのものの表現が比較的コンパクトである場合にのみうまくいくでしょう。 (基本的に一握りの文字列または数値 - ユーザ名、たとえば、またはディレクトリ。ユーザの最近の投稿のすべてのリストなどではありません。)

これらの選択肢のどれが最良であるかに関して - 私は知りません。それはあなたのユースケースに依存します。オプション(1)は単純であるという利点があり、WordPressを2回ロードすることによるパフォーマンスへの影響なしに、必要となる可能性のあるあらゆるWordPressデータにアクセスできることを明確に許可します。 (例えば、使用するスタイルシートやスクリプトのサイズが原因で)強くしない理由がない限り、これはほぼ確実にあなたがすべきことです。

サイズが1ページの重さの点で問題を引き起こすのに十分大きくなるならば、あなたは(2)または(2a)を試すことができます。

そうでなければ - これはおそらくより良い考えです - あなたは静的に指定することができる部分から実際に動的データを利用するスクリプトまたはスタイルシートの部分を分離することを試みることができます。たとえば、#my-fancy要素の背景パラメータを設定するために、WordPressからディレクトリを渡す必要があるスタイルシートがあるとします。これらすべてをhead要素に入れることができます。

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */
 </style>

しかし、なぜそれをする必要があるのでしょうか?ここにはWordPressからのデータに依存する1行しかありません。 WordPressに依存する行だけを分割する方が良いでしょう。

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
 }
 </style>

標準のリンク要素(style.cssなど)を使用してロードする静的スタイルシートに、他のすべてのものを配置します。

 #my-fancy-element {
      /* background-image provided dynamically */
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */

そして、そのカスケードで仕事をさせましょう。

これはJavaScriptでも同じです。

 <script type="text/javascript">
 // Here comes a huge function that uses WordPress data:
 function my_huge_function () {
     // Do a million things ...

     jQuery('#my-fancy').append('<a href="'+<?php json_encode(get_permalink($GLOBALS['post']->ID)); ?>+'">foo</a>);

     // Do a million more things ...

     my_other_function(<?php print json_encode(get_userdata($GLOBALS['post']->post_author); ?>);
 }

 function my_other_function (user) {
     // Do a million things ...
 }
 </script>

代わりにhead要素に次のようなものを入れてください。

 <script type="text/javascript">
 var WordPressPostData = {
 url: <?php print json_encode(get_permalink($GLOBALS['post']->ID)); ?>,
 author: <?php print json_encode(get_userdata($GLOBALS['post']->post_author)); ?>
 }
 </script>

そして、残りを静的なJavaScriptファイルにドロップし、my_huge_function()とmy_other_function()を書き換えて、グローバルのWordPressPostData.urlとWordPressPostData.authorを利用します。

40KのCSSまたは40KのJSは、ほとんど常に動的データに依存する1K以下に、残りは静的外部ファイルで指定してから、カスケード(CSSの場合)またはグローバルアクセス可能のいずれかを使用して再結合できます。変数(グローバル、DOM要素、あるいはあなたが好む他のもの、例えばJS用).

8
radgeek

動的CSSのケースはかなり単純です。

動的CSS定義を<style type="text/css"></style>タグ内に出力する関数を作成し、その関数をwp_print_stylesにフックするだけです。例えば.

<?php
function mytheme_dynamic_css() {
    $options = get_option( 'mytheme_options' );
    ?>
    <style type="text/css">
    /* Dynamic H1 font family */
    h1 { font-family: <?php echo $options['h1_font_family']; ?>;
    </style>
    <?php
}
add_action( 'wp_print_styles', 'mytheme_dynamic_css' );
?>

あるいは、カラースキームがあらかじめ設定されているとしましょう。現在のユーザー設定に従って適切なスタイルシートをエンキューできます。

<?php
function mytheme_enqueue_colorscheme_stylesheet() {
    $options = get_option( 'mytheme_options' );
    $color_scheme = $options['color_scheme'];
    wp_enqueue_style( $colorscheme, get_template_directory_uri() . '/css/' . $color_scheme . '.css' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_colorscheme_stylesheet' );
?>

この場合、WordPressにはwp_enqueue_scriptsアクションフックがないため、この関数はwp_enqueue_stylesにフックします。

5
Chip Bennett

私はしばらくの間それを考えていました。あなたの質問は私にそれを取り戻させる。 いい考えかどうかわからないので、専門家のコメントをお願いします。

What if i phpでjavascript/cssファイルを書く 管理者がデータを保存するとき。ユーザーが再度レイアウトを変更するまでは、1回の書き込みになります(どちらのユーザーも頻繁に変更することはできません)。このようにして、ユーザーがデータを保存するときに一度だけユーザー設定のデータベースにアクセスします。

ファイルを書き込んだ後は、通常のjavascript/cssファイルになるので、テーマがロードされるたびにdatabaseを呼び出す必要はありません。

回答が必要な1つの質問: phpがファイルを書いている瞬間に訪問者がサイトにアクセスしようとするとどうなりますか?

どう考えているか教えてください。

2
Sisir

スクリプトが動的に生成されるなどの理由で別のファイルに含めたくない小さなスクリプトの場合は、WordPress 4.5以降に wp_add_inline_script が用意されています。この関数は基本的にスクリプトを他のスクリプトにラッチします。たとえば、テーマを開発していて、顧客にオプションページから自分のスクリプト(Google AnalyticsやAddThisなど)を挿入できるようにしたいとします。

スタイルには wp_add_inline_style があり、これは基本的に同じように機能します。たとえば、すべてのカスタマイザmodをループ処理して、それらを$all_modsという文字列にまとめるために使用します。これをメインのスタイルシートに次のように追加します。

if (!empty($all_mods)) wp_add_inline_style ('main-style', $all_mods);
1
cjbj