kohanaのテスト12-3・・・スタイルシートやスクリプトのオートローダーを作る
WordPress の HTML を見ると、スタイルシートやスクリプトをオートローダーを使ってリンクしています。WordPress を kohana に移植するために今回は kohana 用のオートローダーを作りました。
オートローダーを使うと、沢山のスクリプトをロードさせる場合に HTML をシンプルに見せることが出来ます。その割には WordPress の新規投稿ページのソースを見ると長々とスクリプトが書いてあったりして見苦しかったりしますけど。
*注1:5月13日に修正あり
準備作業
・WordPress のスタイルシートやスクリプトを別の場所にコピーします。
wordpress\wp-admin\css → \includes\wp\admin\css
wordpress\wp-admin\js → \includes\wp\admin\js
wordpress\wp-admin\images → \includes\wp\admin\images *注1
wordpress\wp-includes\css → \includes\wp\includes\css
wordpress\wp-includes\js → \includes\wp\includes\js
wordpress\wp-includes\images → \includes\wp\includes\images *注1
wordpress\wp-content\themes → \includes\wp\includes\themes *注1
(.php ファイルは使わないので削除)
名前とパスの対応表を作る
WordPress の対応表は wordpress/wp-includes/script-loader.php です。この対応表から抜き取って、kohana の定義ファイルを作ります。
・kohana/application/config/wp-js-css.php
themes\twentyeleven\style.css に対応する定義は無かったので、’twentyeleven' という名前を付けて追加しています。
*注1:パスにミスがあり、更新しました。
<?php defined('SYSPATH') or die('No direct access allowed.'); return array ( 'js' => array ( 'admin-bar' => '/includes/wp/includes/js/admin-bar.js', 'admin-categories' => '/includes/wp/admin/js/categories.js', 'admin-comments' => '/includes/wp/admin/js/edit-comments.js', 'admin-custom-fields' => '/includes/wp/admin/js/custom-fields.js', 'admin-gallery' => '/includes/wp/admin/js/gallery.js', 'admin-tags' => '/includes/wp/admin/js/tags.js', 'admin-widgets' => '/includes/wp/admin/js/widgets.js', 'ajaxcat' => '/includes/wp/admin/js/cat.js', 'autosave' => '/includes/wp/includes/js/autosave.js', 'colorpicker' => '/includes/wp/includes/js/colorpicker.js', 'comment' => '/includes/wp/admin/js/comment.js', 'comment-reply' => '/includes/wp/includes/js/comment-reply.js', 'common' => '/includes/wp/admin/js/common.js', 'cropper' => '/includes/wp/includes/js/crop/cropper.js', 'custom-background' => '/includes/wp/admin/js/custom-background.js', 'dashboard' => '/includes/wp/admin/js/dashboard.js', 'editor' => '/includes/wp/admin/js/editor.js', 'farbtastic' => '/includes/wp/admin/js/farbtastic.js', 'hoverIntent' => '/includes/wp/includes/js/hoverIntent.js', 'image-edit' => '/includes/wp/admin/js/image-edit.js', 'imgareaselect' => '/includes/wp/includes/js/imgareaselect/jquery.imgareaselect.js', 'inline-edit-post' => '/includes/wp/admin/js/inline-edit-post.js', 'inline-edit-tax' => '/includes/wp/admin/js/inline-edit-tax.js', 'jcrop' => '/includes/wp/includes/js/jcrop/jquery.Jcrop.js', 'jquery' => '/includes/wp/includes/js/jquery/jquery.js', 'jquery-color' => '/includes/wp/includes/js/jquery/jquery.color.js', 'jquery-effects-blind' => '/includes/wp/includes/js/jquery/ui/jquery.effects.blind.min.js', 'jquery-effects-bounce' => '/includes/wp/includes/js/jquery/ui/jquery.effects.bounce.min.js', 'jquery-effects-clip' => '/includes/wp/includes/js/jquery/ui/jquery.effects.clip.min.js', 'jquery-effects-core' => '/includes/wp/includes/js/jquery/ui/jquery.effects.core.min.js', 'jquery-effects-drop' => '/includes/wp/includes/js/jquery/ui/jquery.effects.drop.min.js', 'jquery-effects-explode' => '/includes/wp/includes/js/jquery/ui/jquery.effects.explode.min.js', 'jquery-effects-fade' => '/includes/wp/includes/js/jquery/ui/jquery.effects.fade.min.js', 'jquery-effects-fold' => '/includes/wp/includes/js/jquery/ui/jquery.effects.fold.min.js', 'jquery-effects-highlight' => '/includes/wp/includes/js/jquery/ui/jquery.effects.highlight.min.js', 'jquery-effects-pulsate' => '/includes/wp/includes/js/jquery/ui/jquery.effects.pulsate.min.js', 'jquery-effects-scale' => '/includes/wp/includes/js/jquery/ui/jquery.effects.scale.min.js', 'jquery-effects-shake' => '/includes/wp/includes/js/jquery/ui/jquery.effects.shake.min.js', 'jquery-effects-slide' => '/includes/wp/includes/js/jquery/ui/jquery.effects.slide.min.js', 'jquery-effects-transfer' => '/includes/wp/includes/js/jquery/ui/jquery.effects.transfer.min.js', 'jquery-form' => '/includes/wp/includes/js/jquery/jquery.form.js', 'jquery-hotkeys' => '/includes/wp/includes/js/jquery/jquery.hotkeys.js', 'jquery-query' => '/includes/wp/includes/js/jquery/jquery.query.js', 'jquery-serialize-object' => '/includes/wp/includes/js/jquery/jquery.serialize-object.js', 'jquery-table-hotkeys' => '/includes/wp/includes/js/jquery/jquery.table-hotkeys.js', 'jquery-ui-accordion' => '/includes/wp/includes/js/jquery/ui/jquery.ui.accordion.min.js', 'jquery-ui-autocomplete' => '/includes/wp/includes/js/jquery/ui/jquery.ui.autocomplete.min.js', 'jquery-ui-button' => '/includes/wp/includes/js/jquery/ui/jquery.ui.button.min.js', 'jquery-ui-core' => '/includes/wp/includes/js/jquery/ui/jquery.ui.core.min.js', 'jquery-ui-datepicker' => '/includes/wp/includes/js/jquery/ui/jquery.ui.datepicker.min.js', 'jquery-ui-dialog' => '/includes/wp/includes/js/jquery/ui/jquery.ui.dialog.min.js', 'jquery-ui-draggable' => '/includes/wp/includes/js/jquery/ui/jquery.ui.draggable.min.js', 'jquery-ui-droppable' => '/includes/wp/includes/js/jquery/ui/jquery.ui.droppable.min.js', 'jquery-ui-mouse' => '/includes/wp/includes/js/jquery/ui/jquery.ui.mouse.min.js', 'jquery-ui-position' => '/includes/wp/includes/js/jquery/ui/jquery.ui.position.min.js', 'jquery-ui-progressbar' => '/includes/wp/includes/js/jquery/ui/jquery.ui.progressbar.min.js', 'jquery-ui-resizable' => '/includes/wp/includes/js/jquery/ui/jquery.ui.resizable.min.js', 'jquery-ui-selectable' => '/includes/wp/includes/js/jquery/ui/jquery.ui.selectable.min.js', 'jquery-ui-slider' => '/includes/wp/includes/js/jquery/ui/jquery.ui.slider.min.js', 'jquery-ui-sortable' => '/includes/wp/includes/js/jquery/ui/jquery.ui.sortable.min.js', 'jquery-ui-tabs' => '/includes/wp/includes/js/jquery/ui/jquery.ui.tabs.min.js', 'jquery-ui-widget' => '/includes/wp/includes/js/jquery/ui/jquery.ui.widget.min.js', 'json2' => '/includes/wp/includes/js/json2.js', 'link' => '/includes/wp/admin/js/link.js', 'list-revisions' => '/includes/wp/includes/js/wp-list-revisions.js', 'media' => '/includes/wp/admin/js/media.js', 'media-upload' => '/includes/wp/admin/js/media-upload.js', 'nav-menu' => '/includes/wp/admin/js/nav-menu.js', 'password-strength-meter' => '/includes/wp/admin/js/password-strength-meter.js', 'plugin-install' => '/includes/wp/admin/js/plugin-install.js', 'plupload' => '/includes/wp/includes/js/plupload/plupload.js', 'plupload-flash' => '/includes/wp/includes/js/plupload/plupload.flash.js', 'plupload-handlers' => '/includes/wp/includes/js/plupload/handlers.js', 'plupload-html4' => '/includes/wp/includes/js/plupload/plupload.html4.js', 'plupload-html5' => '/includes/wp/includes/js/plupload/plupload.html5.js', 'plupload-silverlight' => '/includes/wp/includes/js/plupload/plupload.silverlight.js', 'post' => '/includes/wp/admin/js/post.js', 'postbox' => '/includes/wp/admin/js/postbox.js', 'prototype' => '/includes/wp/includes/js/prototype.js', 'quicktags' => '/includes/wp/includes/js/quicktags.js', 'sack' => '/includes/wp/includes/js/tw-sack.js', 'schedule' => '/includes/wp/includes/js/jquery/jquery.schedule.js', 'scriptaculous-builder' => '/includes/wp/includes/js/scriptaculous/builder.js', 'scriptaculous-controls' => '/includes/wp/includes/js/scriptaculous/controls.js', 'scriptaculous-dragdrop' => '/includes/wp/includes/js/scriptaculous/dragdrop.js', 'scriptaculous-effects' => '/includes/wp/includes/js/scriptaculous/effects.js', 'scriptaculous-root' => '/includes/wp/includes/js/scriptaculous/wp-scriptaculous.js', 'scriptaculous-slider' => '/includes/wp/includes/js/scriptaculous/slider.js', 'scriptaculous-sound' => '/includes/wp/includes/js/scriptaculous/sound.js', 'set-post-thumbnail' => '/includes/wp/admin/js/set-post-thumbnail.js', 'suggest' => '/includes/wp/includes/js/jquery/suggest.js', 'swfobject' => '/includes/wp/includes/js/swfobject.js', 'swfupload' => '/includes/wp/includes/js/swfupload/swfupload.js', 'swfupload-all' => '/includes/wp/includes/js/swfupload/swfupload-all.js', 'swfupload-handlers' => '/includes/wp/includes/js/swfupload/handlers.js', 'swfupload-queue' => '/includes/wp/includes/js/swfupload/plugins/swfupload.queue.js', 'swfupload-speed' => '/includes/wp/includes/js/swfupload/plugins/swfupload.speed.js', 'swfupload-swfobject' => '/includes/wp/includes/js/swfupload/plugins/swfupload.swfobject.js', 'theme' => '/includes/wp/admin/js/theme.js', 'theme-preview' => '/includes/wp/admin/js/theme-preview.js', 'thickbox' => '/includes/wp/includes/js/thickbox/thickbox.js', 'user-profile' => '/includes/wp/admin/js/user-profile.js', 'utils' => '/includes/wp/admin/js/utils.js', 'word-count' => '/includes/wp/admin/js/word-count.js', 'wp-ajax-response' => '/includes/wp/includes/js/wp-ajax-response.js', 'wpdialogs' => '/includes/wp/includes/js/tinymce/plugins/wpdialogs/js/wpdialog.js', 'wpdialogs-popup' => '/includes/wp/includes/js/tinymce/plugins/wpdialogs/js/popup.js', 'wp-fullscreen' => '/includes/wp/admin/js/wp-fullscreen.js', 'wplink' => '/includes/wp/includes/js/wplink.js', 'wp-lists' => '/includes/wp/includes/js/wp-lists.js', 'wp-pointer' => '/includes/wp/includes/js/wp-pointer.js', 'xfn' => '/includes/wp/admin/js/xfn.js', ), 'css' => array ( 'admin-bar' => '/includes/wp/includes/css/admin-bar.css', 'colors-classic' => '/includes/wp/admin/css/colors-classic.css', 'colors-fresh' => '/includes/wp/admin/css/colors-fresh.css', 'editor-buttons' => '/includes/wp/includes/css/editor-buttons.css', 'farbtastic' => '/includes/wp/admin/css/farbtastic.css', 'ie' => '/includes/wp/admin/css/ie.css', 'imgareaselect' => '/includes/wp/includes/js/imgareaselect/imgareaselect.css', 'install' => '/includes/wp/admin/css/install.css', 'jcrop' => '/includes/wp/includes/js/jcrop/jquery.Jcrop.css', 'media' => '/includes/wp/admin/css/media.css', 'thickbox' => '/includes/wp/includes/js/thickbox/thickbox.css', 'twentyeleven' => '/includes/wp/themes/twentyeleven/style.css', 'wp-admin' => '/includes/wp/admin/css/wp-admin.css', 'wp-jquery-ui-dialog' => '/includes/wp/includes/css/jquery-ui-dialog.css', 'wp-pointer' => '/includes/wp/includes/css/wp-pointer.css', ), );
オートローダーを作る
WordPress のオートローダーは wordpress/wp-admin/load-styles.php と load-scripts.php です。これを参考にして作りました。元のコードにはないテスト機能を追加しています。引数に c=test を付けてアクセスするとロードしたファイルのリストと中身を text/plain 属性で出力します。
・kohana/application/classes/controller/loadcss.php
スタイルシート用のオートローダーです。30行目にドキュメントルートの絶対パスを書いているので、必要に応じて書きなおして下さい。
*注1:URL を記述しているスタイルシートの場合リンクが狂うので修正しました。
引数に dir=rtl を付けて使います。
スタイルシートは多くないので、直接リンクを書いた方が良いかも。
<?php defined('SYSPATH') OR die('No direct access allowed.'); class Controller_Loadcss extends Controller { public function action_index() { error_reporting(0); $load = preg_replace('/[^a-z0-9,_-]+/i', '', $_GET['load']); $load = explode(',', $load); if (empty($load)) exit; $compress = ( isset($_GET['c']) && $_GET['c'] ); $force_gzip = ( $compress && 'gzip' == $_GET['c'] ); $rtl = ( isset($_GET['dir']) && 'rtl' == $_GET['dir'] ); $test = ( isset($_GET['c']) AND $_GET['c'] == 'test'); $expires_offset = 31536000; $out = ''; $pathlist = ''; $config = Kohana::$config->load('wp-js-css')->css; foreach ($load as $handle) { if (!$config[$handle]) { $pathlist .= '*** ' . $handle . " is not defined! ***\n"; continue; } $path = 'c:/xampp/htdocs' . $config[$handle]; $pathlist .= $path . "\n"; $content = file_get_contents($path) . "\n"; if ($rtl) { $dir = dirname($config[$handle]); $content = str_replace('../images/', $dir . '/../images/', $content); $content = str_replace('url(images/', 'url('.$dir . '/images/', $content); } $out .= $content; } if ($test) { header('Content-Type: text/plain; charset=UTF-8'); header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $expires_offset) . ' GMT'); header("Cache-Control: public, max-age=$expires_offset"); print $pathlist . "\n"; echo $out; exit; } else { header('Content-Type: text/css'); header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $expires_offset) . ' GMT'); header("Cache-Control: public, max-age=$expires_offset"); if ($compress && !ini_get('zlib.output_compression') && 'ob_gzhandler' != ini_get('output_handler') && isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { header('Vary: Accept-Encoding'); // Handle proxies if (false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && !$force_gzip) { header('Content-Encoding: deflate'); $out = gzdeflate($out, 3); } elseif (false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode')) { header('Content-Encoding: gzip'); $out = gzencode($out, 3); } } echo $out; exit; } } }
・kohana/application/classes/controller/loadjs.php
Javascript 用のオートローダーです。30行目にドキュメントルートの絶対パスを書いているので、必要に応じて書きなおして下さい。
<?php defined('SYSPATH') OR die('No direct access allowed.'); class Controller_Loadjs extends Controller { public function action_index() { error_reporting(0); $load = preg_replace('/[^a-z0-9,_-]+/i', '', $_GET['load']); $load = explode(',', $load); if (empty($load)) exit; $compress = ( isset($_GET['c']) && $_GET['c'] ); $force_gzip = ( $compress && 'gzip' == $_GET['c'] ); $test = ( isset($_GET['c']) AND $_GET['c'] == 'test'); $expires_offset = 31536000; $out = ''; $pathlist = ''; $config = Kohana::$config->load('wp-js-css')->js; foreach ($load as $handle) { if (!$config[$handle]){ $pathlist .= '*** '.$handle." is not defined! ***\n"; continue; } $path = 'c:/xampp/htdocs' . $config[$handle]; $pathlist .= $path . "\n"; $out .= file_get_contents($path) . "\n"; } if ($test) { header('Content-Type: text/plain; charset=UTF-8'); header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $expires_offset) . ' GMT'); header("Cache-Control: public, max-age=$expires_offset"); echo $pathlist."\n"; echo $out; exit; } else { header('Content-Type: application/x-javascript; charset=UTF-8'); header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $expires_offset) . ' GMT'); header("Cache-Control: public, max-age=$expires_offset"); if ($compress && !ini_get('zlib.output_compression') && 'ob_gzhandler' != ini_get('output_handler') && isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { header('Vary: Accept-Encoding'); // Handle proxies if (false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && !$force_gzip) { header('Content-Encoding: deflate'); $out = gzdeflate($out, 3); } elseif (false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode')) { header('Content-Encoding: gzip'); $out = gzencode($out, 3); } } echo $out; exit; } } }
試験
WordPress の新規投稿画面では沢山の Javascript を使っています。沢山ロードしている部分を今回のローダーで記述すると下記例のようになります。ブラウザで試してみて下さい。実戦では c=test& を省いて使います。
http://localhost/kohana/loadjs?c=test&load=admin-bar,hoverIntent,common,jquery-color,schedule,wp-ajax-response,autosave,suggest,wp-lists,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,postbox,post,thickbox,media-upload,word-count,editor,quicktags,jquery-ui-resizable,jquery-ui-draggable,jquery-ui-button,jquery-ui-position,jquery-ui-dialog,wpdialogs,wplink,wpdialogs-popup,wp-fullscreen