it-swarm.com.de

Wie verwende ich WordPress (PHP) -Funktionen in AngularJS-Partials-Dateien?

Ich verwende AngularJS, um eine Liste meiner WordPress-Posts zu laden, kann jedoch keine meiner PHP -Funktionen für die Arbeit mit meiner Partials-Datei verwenden.

Ich habe versucht, etwas wie search.php anstelle von search.html zu verwenden. Dabei erhalte ich jedoch Fehler wie einen schwerwiegenden Fehler. Get_post_meta ist undefiniert.

Jetzt weiß ich, dass wir keine Client-Seite mit Server-Seite mischen sollen, und ich kann möglicherweise irgendeine Art von Dienst verwenden, um mein PHP zu analysieren, aber ich habe keine Ahnung, wie ich vorgehen soll. Ich benötige meinen search.php, um meine PHP Tags zu rendern, damit ich benutzerdefinierte Felder anzeigen und verschiedene PHP Funktionen verwenden kann, die ich dort habe.

Wie geht das am besten?

Auf meiner Seitenvorlage (.php) habe ich -

<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>
            &copy; <?php echo date( 'Y' ); ?>
        </footer>
    </div>

Und in meiner PHP -Datei, die ich aufrufen möchte, gibt es Funktionen wie:

<?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); ?>

Mathematik --

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; ?>

Und Funktionen -

<?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'));} ?>

Wie kann ich dies mit ng-view und meinen Teilvorlagen erreichen?

UPDATE

So sieht mein aktuelles Setup aus - Zuerst habe ich eine Seitenvorlage namens 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>
            &copy; <?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>

Dann mein App-Skript ohne Aufrufen der PHP-Datei als Teil -

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);

Dann ist die Teildatei eine search.php-Datei mit den Funktionen und dem Code, die in meiner ursprünglichen Frage gezeigt wurden.

1
Rich

1) URL umschreiben

Ich bin hübsch teilweise zu url umschreibt . Sie sind einfach einzurichten, anzupassen und Sie erhalten Zugriff auf alles von WordPress.

In der folgenden Klasse können Sie sehen, dass umgeschrieben hinzugefügt wird (Sie müssen die Umschreiberegeln nur einmal löschen ) und wenn ein Teil der URL übereinstimmt, können Abschnitte als dynamische Variablen verwendet werden (regEx -> query_vars ). Der lustige Teil ist, dass Sie die Anfrage jederzeit beenden können, um JSON-Daten zurückzugeben, oder WordPress dies zusätzlich zur Angabe der zu verwendenden Vorlage Seite tun lassen können.

Wir richten also eine Front-End-Anfrage für:

example.com/api/angular/partial/custom

in etwas, das wir intern verwenden können als:

example.com/index.php?__api_angular=1&partial=custom

Bei der Registrierung des Befehls rewrite - sollte in regEx noch etwas hinzugefügt werden, aber ich denke, das bringt den Punkt auf den Punkt.

Diese Klasse kann wirklich überall hinzugefügt werden (functions.php/plugins). Es instanziiert sich selbst und bindet das, was es in init() benötigt. Persönlich verwende ich gerne eine Klasse, weil der Code enthalten ist und keine Konflikte auftreten, wenn die Klasse an einer anderen Stelle definiert ist. Nun, die Klasse wird nicht neu erstellt, wenn sie bereits definiert ist.

<?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 Wird als Vorlage für example.com/api/angular/partial/custom verwendet

<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>

2) Restroute

Da Sie bereits wp-json verwenden, können Sie auch eine benutzerdefinierte Restroute erstellen. Hier ist weniger Setup erforderlich, was von Vorteil ist.

<?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
1
jgraup

Was funktioniert, ist der Aufruf des Ajax-Endpunkts von WP. Beachten Sie, dass dies nicht die Adresse Ihres Teils ist, sondern die feste WP Adresse für alle AJAX Aufrufe

wp_localize_script('handle', 'myLocalized', array(
     'ajaxUrl' => admin_url( 'admin-ajax.php' )
) );

gibt die Endpunktadresse im JS-Objekt myLocalized an. Sie senden alle Anforderungen an diese Seite und beziehen sich auf Ihre Teilanforderungen nur als GET-Parameter:

$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'
});

Alle Aufrufe von admin-ajax.php mit einem Parameter {action} werden an Aktionen mit dem Namen wp_ajax_{action} (für angemeldete Benutzer) oder wp_ajax_nopriv_{action} (für nicht angemeldete Benutzer) weitergeleitet. Auf der Serverseite können Sie sich mit ihnen verbinden und Ihre Partials einbinden:

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' );

Auf diese Weise ist WordPress vollständig initialisiert und kann alle normalerweise verfügbaren Funktionen ausführen. (Nun, außerhalb der Schleife.)

Da Sie bestimmte Posts vom Controller und über den wp-json-Endpunkt auswählen, sollten Sie dies tun.

1
ccprog