首页 > 解决方案 > Trying to create a shortcode to insert a react app

问题描述

I need to integrate a react application inside a wordpress website. I created a custom plugin and a shortcode but the shortcode renders an empty div. It's my first wordpress plugin so I might be missing something.

My plugin directory looks like this:

/public_html/wp-content/plugins/PatSearch
 - PatSearch.php
/public_html/wp-content/plugins/PatSearch/includes
 - enqueue.php
 - shortcode.php
/public_html/wp-content/plugins/PatSearch/widget
 - Contains the root of the react application. It has been build and works when I visit the build directory

PatSearch.php

<?php
/**
 * @wordpress-plugin
 * Plugin Name:       Ajout d'un app React pour la recherche
 */

defined( 'ABSPATH' ) or die( 'Direct script access diallowed.' );

define( 'PAT_WIDGET_PATH', plugin_dir_path( __FILE__ ) . '/widget' );
define( 'PAT_ASSET_MANIFEST', PAT_WIDGET_PATH . '/build/asset-manifest.json' );
define( 'PAT_INCLUDES', plugin_dir_path( __FILE__ ) . '/includes' );

require_once( PAT_INCLUDES . '/enqueue.php' );
require_once( PAT_INCLUDES . '/shortcode.php' );

enqueue.php

<?php
// This file enqueues scripts and styles

defined( 'ABSPATH' ) or die( 'Direct script access disallowed.' );

add_action( 'init', function() {

    add_filter( 'script_loader_tag', function( $tag, $handle ) {
      if ( ! preg_match( '/^pat-/', $handle ) ) { return $tag; }
      return str_replace( ' src', ' async defer src', $tag );
    }, 10, 2 );

    add_action( 'wp_enqueue_scripts', function() {

        $asset_manifest = json_decode( file_get_contents( PAT_ASSET_MANIFEST ), true )['files'];

        if ( isset( $asset_manifest[ 'main.css' ] ) ) {
          wp_enqueue_style( 'pat', get_site_url() . $asset_manifest[ 'main.css' ] );
        }

        wp_enqueue_script( 'pat-runtime', get_site_url() . $asset_manifest[ 'runtime~main.js' ], array(), null, true );

        wp_enqueue_script( 'pat-main', get_site_url() . $asset_manifest[ 'main.js' ], array('pat-runtime'), null, true );

        foreach ( $asset_manifest as $key => $value ) {
          if ( preg_match( '@static/js/(.*)\.chunk\.js@', $key, $matches ) ) {
            if ( $matches && is_array( $matches ) && count( $matches ) === 2 ) {
              $name = "pat-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
              wp_enqueue_script( $name, get_site_url() . $value, array( 'pat-main' ), null, true );
            }
          }

          if ( preg_match( '@static/css/(.*)\.chunk\.css@', $key, $matches ) ) {
            if ( $matches && is_array( $matches ) && count( $matches ) == 2 ) {
              $name = "pat-" . preg_replace( '/[^A-Za-z0-9_]/', '-', $matches[1] );
              wp_enqueue_style( $name, get_site_url() . $value, array( 'pat' ), null );
            }
          }
        }

    });
});

shortcode.php

<?php
// This file enqueues a shortcode.

defined( 'ABSPATH' ) or die( 'Direct script access disallowed.' );

add_shortcode( 'pat_widget', function( $atts ) {
  $default_atts = array();
  $args = shortcode_atts( $default_atts, $atts );

  return "<div id='pat-root'></div>";
});

I created a page and added the shortcode [pat_widget] saved it and visited the page but the react application located at /wp-content/plugins/PatSearch/widget/build/ was not embed like I thought ... When I look at the source code of the page, I can only see an empty <div id='pat-root'></div>

标签: node.jsreactjswordpress

解决方案


I found what the problem was. The wordpress side of things was working fine ... I had to modify the React index.js file that was generated in the build.

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

// Commented this line
// ReactDOM.render(<App />, document.getElementById("root"));

// Added this to match my shortcode requirements
const target = document.getElementById('pat-root');
if (target) { ReactDOM.render(<App />, target); }

推荐阅读