私はWordPressの投稿のリストを読み込むためにAngularJSを使用していますが、PHP関数をパーシャルファイルで使用することはできません。
search.php
の代わりにsearch.html
のようなものを使用しようとしましたが、そうすると致命的なエラーget_post_metaのようなエラーが発生します.
クライアント側とサーバー側を混在させることは想定されていませんし、PHPを解析するために何らかのサービスを使用することもできますが、その方法についてはわかりません。カスタムフィールドを表示できるようにPHPタグをレンダリングし、そこにあるいくつかのPHP関数を使用するには、search.php
が必要です。
これを行う最善の方法は何ですか?
私のページテンプレート(.php
)に私は -
<div id="page" ng-app="app">
<header>
<h1>
<a href="<?php echo home_url(); ?>">Search</a>
</h1>
</header>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<div ng-Cloak ng-controller="MyController" class="my-controller">
<div ng-view></div>
</div>
<?php endwhile; ?>
<?php endif; ?>
<?php rewind_posts(); ?>
<div ng-controller="OtherController" class="other-controller">
<div class="text-center">
<dir-pagination-controls boundary-links="true" on-page-change="pageChangeHandler(newPageNumber)" template-url="/partials/dirPagination.tpl.html"></dir-pagination-controls>
</div>
</div>
<footer>
© <?php echo date( 'Y' ); ?>
</footer>
</div>
そして私のPHPファイルに表示させたいのは -
<?php
$pcomp1b = get_post_meta(get_the_ID(), 'pa_meta_comp1b', true);
$pcomp1c = get_post_meta(get_the_ID(), 'pa_meta_comp1c', true);
$pcomp1d = get_post_meta(get_the_ID(), 'pa_meta_comp1d', true); ?>
数学 -
if( is_numeric( $price1 ) ) {
$a1 = $price1;
}
$b1 = $pcomp1d;
$sqft1 = str_replace( ',', '', $b1 );
if( is_numeric( $sqft1 ) ) {
$b1 = $sqft1;
}
$a2 = $pcomp2f;
$price2 = str_replace( ',', '', $a2 );
if( is_numeric( $price2 ) ) {
$a2 = $price2;
}
$b2 = $pcomp2d;
$sqft2 = str_replace( ',', '', $b2 );
if( is_numeric( $sqft2 ) ) {
$b2 = $sqft2;
}
$a3 = $pcomp3f;
$price3 = str_replace( ',', '', $a3 );
if( is_numeric( $price3 ) ) {
$a3 = $price3;
}
$b3 = $pcomp3d;
$sqft3 = str_replace( ',', '', $b3 );
if( is_numeric( $sqft3 ) ) {
$b3 = $sqft3;
}
$ppsqft1 = ROUND($price1 / $sqft1);
$ppsqft2 = ROUND($price2 / $sqft2);
$ppsqft3 = ROUND($price3 / $sqft3);
$ppsav = ROUND((($ppsqft1 + $ppsqft2 + $ppsqft3)/3));
$b4 = $property_area;
$parea = str_replace( ',', '', $b4 );
if( is_numeric( $parea ) ) {
$b4 = $parea;
}
$ehvp = $ppsav * $parea;
$homevalue = number_format($ehvp, 0, '.', ',');
echo '$' . $homevalue; ?>
そして機能 -
<?php if (class_exists('MRP_Multi_Rating_API')){ MRP_Multi_Rating_API::display_rating_result(array('rating_item_ids' => 2, 'show_count' => false, 'result_type' => 'value_rt', 'no_rating_results_text' => 'N/A'));} ?>
それでどうやってこれをng-view
と私のパーシャルテンプレートで動作させることができますか?
_アップデート_
これが私の現在の設定がどのように見えるかです - 最初に私はsearch-results.phpと呼ばれるページテンプレートを持っています -
<?php
/* Template Name:Search Results */ ?>
<!DOCTYPE html>
<html>
<head>
<base href="<?php $url_info = parse_url( home_url() ); echo trailingslashit( $url_info['path'] ); ?>">
<title>Search</title>
<link rel="stylesheet" type="text/css" href="/style.css" media="print" />
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.3.0.min.js"></script>
<?php wp_head(); ?>
</head>
<body>
<div id="page" ng-app="app">
<header>
<h1>
<a href="<?php echo home_url(); ?>">Search</a>
</h1>
</header>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<div ng-Cloak ng-controller="MyController" class="my-controller">
<div ng-view></div></div>
<?php endwhile; ?>
<?php endif; ?>
<?php rewind_posts(); ?>
<div ng-controller="OtherController" class="other-controller">
<div class="text-center">
<dir-pagination-controls boundary-links="true" on-page-change="pageChangeHandler(newPageNumber)" template-url="/partials/dirPagination.tpl.html"></dir-pagination-controls>
</div>
</div>
<footer>
© <?php echo date( 'Y' ); ?>
</footer>
</div>
<script>
function getdata($scope,$http){
$http.get("/wp-json/posts?type=property")
.success(function(data)
{$scope.result = data;}
);
}
</script>
<?php wp_footer(); ?>
</body>
</html>
それから部分的にphpファイルを呼び出さずに私のアプリのスクリプト -
var app = angular.module('app', ['ngRoute', 'ngSanitize', 'angularUtils.directives.dirPagination'])
function MyController($scope) {
$scope.currentPage = 1;
$scope.pageSize = 2;
$scope.posts = [];
$scope.pageChangeHandler = function(num) {
console.log('search page changed to ' + num);
};
}
function OtherController($scope) {
$scope.pageChangeHandler = function(num) {
console.log('going to page ' + num);
};
}
app.config(function(paginationTemplateProvider) {
paginationTemplateProvider.setPath('/partials/dirPagination.tpl.html');
});
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/search-results', {
templateUrl: myLocalized.partials + 'main.html',
controller: 'Main'
})
.when('/:ID', {
templateUrl: myLocalized.partials + 'content.html',
controller: 'Content'
});
})
app.controller('Main', function($scope, $http, $routeParams) {
$http.get('wp-json/posts?type=property').success(function(res){
$scope.posts = res;
});
})
app.controller('Content', function($scope, $http, $routeParams) {
$http.get('wp-json/posts?type=property/?filter["posts_per_page"]=25&filter["orderby"]=date&filter["order"]=desc/' + $routeParams.ID).success(function(res){
$scope.post = res;
});
});
app.controller('MyController', MyController);
app.controller('OtherController', OtherController);
それから部分的なファイルは私の最初の質問で示された機能とコードを持つsearch.phpファイルになるでしょう。
私は可愛い partial url rewritees にしています。セットアップ、カスタマイズが簡単で、WordPressのすべてにアクセスできます。
以下のクラスでは、 rewritees が追加されています( rewriteルールをフラッシュします を1回だけ実行する必要があります)。 (regEx - > query_vars )。面白いのは、JSONデータを返すためにいつでもリクエストを強制終了できること、または使用する template ページを指定することに加えてWordPressにそれを実行させることです。
だから我々はフロントエンドの要求をオンにするつもりです:
example.com/api/angular/partial/custom
内部的に使用できるものとして
example.com/index.php?__api_angular=1&partial=custom
rewrite を登録するとき、regExに何か特別なものを追加する必要があります - しかし、これが問題になると思います。
このクラスは実際にはどこにでも追加できます( functions.php // plugins )。それは自分自身をインスタンス化し、それがinit()
に必要なものをフックする。個人的には、コードが含まれていて、クラスがどこか他の場所で定義されていても競合しないので、私はクラスを使用するのが好きです。
<?php
if ( ! class_exists( 'AngularEndpoint' ) ):
class AngularEndpoint {
const ENDPOINT_QUERY_NAME = 'api/angular';
const ENDPOINT_QUERY_PARAM = '__api_angular';
// WordPress hooks
public function init() {
add_filter( 'query_vars', array ( $this, 'add_query_vars' ), 0 );
add_action( 'parse_request', array ( $this, 'sniff_requests' ), 0 );
add_action( 'init', array ( $this, 'add_endpoint' ), 0 );
}
// Add public query vars
public function add_query_vars( $vars ) {
// add all the things we know we'll use
$vars[] = static::ENDPOINT_QUERY_PARAM;
$vars[] = 'partial';
$vars[] = 'filter';
$vars[] = 'type';
return $vars;
}
// Add API Endpoint
public function add_endpoint() {
add_rewrite_rule( '^' . static::ENDPOINT_QUERY_NAME . '/partial/([^/]*)/?', 'index.php?' . static::ENDPOINT_QUERY_PARAM . '=1&partial=$matches[1]', 'top' );
//////////////////////////////////
flush_rewrite_rules( false ); //// <---------- REMOVE THIS WHEN DONE
//////////////////////////////////
}
// Sniff Requests
public function sniff_requests( $wp_query ) {
global $wp;
if ( isset(
$wp->query_vars[ static::ENDPOINT_QUERY_PARAM ],
$wp->query_vars[ 'partial' ] ) ) {
$this->handle_partial_request(); // handle it
}
}
// Handle Requests
protected function handle_partial_request() {
global $wp;
$partial_requested = $wp->query_vars[ 'partial' ];
switch ( $partial_requested ) {
// example.com/api/angular/partial/ping
case 'ping':
wp_send_json_success( array (
'message' => 'Enjoy your partial', 'partial' => $partial_requested,
) );
break;
// example.com/api/angular/partial/custom
case 'custom':
add_filter( 'template_include', function( $original_template ) {
return __DIR__ . '/custom.php';
} );
break;
// example.com/api/angular/partial/search
case 'search':
add_filter( 'template_include', function( $original_template ) {
return get_template_directory() . '/search.php';
} );
break;
default:
wp_send_json_error( array ( 'message' => 'Invalid Request' ) );
}
}
}
$wpAngularEndpoint = new AngularEndpoint();
$wpAngularEndpoint->init();
endif; // AngularEndpoint
custom.php example.com/api/angular/partial/customのテンプレートとして使用されます。
<html>
<body>
<h1>Custom Stuff</h1>
<h2><?php echo "PHP Stuff" ?></h2>
<?php
$posts = get_posts();
?>
<ul>
<?php
foreach ( $posts as $post ) {
echo '<li>' . $post->post_title . '</li>' . PHP_EOL;
}
?>
</ul>
</body>
</html>
もう1つの選択肢は、既にwp-json
を使用しているため、カスタムの rest route を作成することです。ここで必要とされるより少ないセットアップがあります。
<?php
if ( ! class_exists( 'AngularJSONEndpoint' ) ):
class AngularJSONEndpoint {
const ENDPOINT_NAMESPACE = 'namespace/v2';
/**
* Initialize WordPress hooks
*/
public function init() {
add_action( 'init', array ( $this, 'add_endpoint' ), 0 );
}
/**
* Add JSON API Endpoint
*/
public function add_endpoint() {
add_action('rest_api_init', function () {
// http://example.com/wp-json/namespace/v2/angular?partial=custom
register_rest_route( static::ENDPOINT_NAMESPACE, '/angular', array (
'methods' => 'GET',
'callback' => array($this, 'wp_json_namespace_v2__angular'),
'permission_callback' => function (WP_REST_Request $request) {
return true;
}
));
});
flush_rewrite_rules(true); // FIXME: <------- DONT LEAVE ME HERE
}
/**
* Handle the endpoint
* @param $request
*
* @return WP_REST_Response
*/
function wp_json_namespace_v2__angular($request)
{
// json-api params
$parameters = $request->get_query_params();
// check for partial requests
if(isset($parameters['partial'])){
switch($parameters['partial']) {
case 'custom':
require __DIR__ . '/custom.php';
die();
}
}
// return results
$data = array(
'success' => false,
'message' => 'Bad Request'
);
return new WP_REST_Response($data, 400);
}
}
$wpAngularJSONEndpoint = new AngularJSONEndpoint();
$wpAngularJSONEndpoint->init();
endif; // AngularJSONEndpoint
うまくいっているのは、WPのAjaxエンドポイントを呼び出すことです。これはパーシャルのアドレスではなく、すべてのWP呼び出しの固定のAJAXアドレスです。
wp_localize_script('handle', 'myLocalized', array(
'ajaxUrl' => admin_url( 'admin-ajax.php' )
) );
jSオブジェクトmyLocalized
内のエンドポイントアドレスを提供します。あなたはそのページにすべてのリクエストを送り、あなたのパーシャルをGETパラメータとしてのみ参照します。
$routeProvider.when('/search-results', {
templateUrl: myLocalized.ajaxUrl + '?action=get_my_partial&partial=' + 'main';
controller: 'Main'
}).when('/:ID', {
templateUrl: myLocalized.ajaxUrl + '?action=get_my_partial&partial=' + 'content';
controller: 'Content'
});
パラメータadmin-ajax.php
を指定した{action}
へのすべての呼び出しは、wp_ajax_{action}
(ログインユーザーの場合)またはwp_ajax_nopriv_{action}
(ログインしていないユーザーの場合)という名前のアクションにルーティングされます。サーバーサイドでは、それらに接続してパーシャルを含めることができます。
function get_the_partials () {
switch ( $_GET['partial'] ) {
case 'main':
// check authorization
include plugin_dir_path(__FILE__) .'/partials/main.html';
break;
case 'content':
// check authorization
include plugin_dir_path(__FILE__) .'/partials/content.html';
break;
default:
wp_die( 'Nothing found.' );
break;
}
die();
}
add_action( 'wp_ajax_nopriv_get_my_partial', 'get_the_partials' );
add_action( 'wp_ajax_get_my_partial', 'get_the_partials' );
このようにして、WordPressは完全に初期化され、通常利用可能な機能を処理することができます。 (まあ、ループの外側)
あなたがコントローラからそしてwp-jsonエンドポイントを通して特定の投稿を選択することを扱うので、それはそれをするべきです。