Czy można używać wp_localize_script do tworzenia globalnych zmiennych JS bez określonego uchwytu skryptu?

27

Czy możemy w jakiś sposób użyć wp_localize_script () do tworzenia globalnych zmiennych js bez określonego uchwytu skryptu, do którego można uzyskać dostęp ze wszystkich plików js, nawet jeśli skrypty js nie są poprawnie kolejkowane przy użyciu wp_enqueue_script?

Korzystam z tego kodu, który tworzy zmienną dla uchwytu „ajaxscript”, więc nie mogę uzyskać dostępu do obiektu „ajaxobject” w pliku js, który jest zawarty w pliku header.php bezpośrednio przez <script src="xxx" .... />

wp_register_script( 'ajaxscript', get_bloginfo( 'template_url' ) . '/js/ajaxscript.js', array(), $version );
wp_enqueue_script( 'ajaxscript' );
wp_localize_script( 'ajaxscript', 'ajaxobject',
    array( 
        'ajaxurl'   => admin_url( 'admin-ajax.php' ),
        'ajaxnonce' => wp_create_nonce( 'itr_ajax_nonce' )
    )
);
Subharanjan
źródło
5
Po prostu dodaj wbudowany JS do motywu. I tak właśnie się wp_localize_scriptdzieje. W przypadku obu metod zmienne są dostępne z dowolnego skryptu
onetrickpony
3
Jeśli masz kontrolę nad skryptami, jak skończyłbyś ze skryptem w głowie, który nie został poprawnie umieszczony w kolejce? Pojęcie wp_localize_script polega na tym, że udostępniasz skryptowi - który ładujesz poprawnie za pomocą wp_enqueue_script. W którym przypadku świadomie załadowałbyś skrypt do pliku nagłówkowego, który potrzebował tych zmiennych, zamiast ładować go za pomocą skryptu wp_enqueue_script?
cale_b
@cale_b: Istnieje skrypt, który jest już zawarty w nagłówku.php i zawiera wiele skryptów, które zaczynają się psuć, gdy próbuję kolejkować ten plik js przez wp_enqueue_script. Muszę wykonać wywołanie ajax z tego pliku skryptu. Zamiast przełamać funkcjonalność i naprawić jeden po drugim, potrzebowałem szybkiego rozwiązania. Nawet nie jestem pewien, która część strony się psuje z powodu niewielkiej zmiany „wp_enqueue_script” :(
Subharanjan
Słusznie. Tak jak wskazówka, pobierz Firebug dla Firefoksa i możesz używać konsoli do oglądania / wyświetlania błędów javascript. Nieocenione narzędzie do rozwiązywania problemów.
cale_b

Odpowiedzi:

22

W takim przypadku zamiast używać wp_localize_script, możesz podpiąć swoje zmienne js na wp_head, w ten sposób byłoby ono dostępne dla wszystkich plików js, takich jak:

function my_js_variables(){ ?>
      <script type="text/javascript">
        var ajaxurl = '<?php echo admin_url( "admin-ajax.php" ); ?>';
        var ajaxnonce = '<?php echo wp_create_nonce( "itr_ajax_nonce" ); ?>';
      </script><?php
}
add_action ( 'wp_head', 'my_js_variables' )

Ponadto, jak sugeruje @Weston Ruter, możesz json zakodować zmienne:

add_action ( 'wp_head', 'my_js_variables' );
function my_js_variables(){ ?>
  <script type="text/javascript">
    var ajaxurl = <?php echo json_encode( admin_url( "admin-ajax.php" ) ); ?>;      
    var ajaxnonce = <?php echo json_encode( wp_create_nonce( "itr_ajax_nonce" ) ); ?>;
    var myarray = <?php echo json_encode( array( 
         'foo' => 'bar',
         'available' => TRUE,
         'ship' => array( 1, 2, 3, ),
       ) ); ?>
  </script><?php
}
Kumar
źródło
4
Powinieneś użyć json_encodetutaj, na przykład:var ajaxurl = <?php echo json_encode( admin_url( "admin-ajax.php" ) ); ?>;
Weston Ruter
Dobrze, dodam to teraz
Kumar,
12

Możesz eksportować dowolne dane, które chcesz przechwycić wp_head, jak pokazują powyższe odpowiedzi. Należy jednak użyć json_encodedo przygotowania danych PHP do eksportu do JS zamiast prób osadzenia surowych wartości w literałach JS:

function my_js_variables(){
    ?>
    <script>
    var ajaxurl = <?php echo json_encode( admin_url( "admin-ajax.php" ) ) ?>;
    var ajaxnonce = <?php echo json_encode( wp_create_nonce( "itr_ajax_nonce" ) ) ?>;
    var myarray = <?php echo json_encode( array( 
        'food' => 'bard',
        'bard' => false,
        'quux' => array( 1, 2, 3, ),
    ) ) ?>;
    </script>
    <?php
}
add_action ( 'wp_head', 'my_js_variables' )

Użycie json_encodeułatwia sobie i zapobiega przypadkowym błędom składni, jeśli łańcuch zawiera znaki cudzysłowu. Co jeszcze ważniejsze, przy użyciu json_encodeThwarts XSS.

Weston Ruter
źródło
1

Skończyło się na tym. Teraz działa !! Dzięki @ dot1

function itr_global_js_vars() {
    $ajax_url = 'var itrajaxobject = {"itrajaxurl":"'. admin_url( 'admin-ajax.php' ) .'", "itrajaxnonce":"'. wp_create_nonce( 'itr_ajax_nonce' ) .'"};';
    echo "<script type='text/javascript'>\n";
    echo "/* <![CDATA[ */\n";
    echo $ajax_url;
    echo "\n/* ]]> */\n";
    echo "</script>\n";
}
add_action( 'wp_head', 'itr_global_js_vars' );
Subharanjan
źródło
8
Powinieneś użyć json_encodezamiast ręcznie tworzyć JSON.
Weston Ruter
Używam json_encodeteraz :) Dzięki @WestonRuter !!
Subharanjan
0

Chociaż nie jest to moja najlepsza praca, jest to kolejny prosty sposób na uzyskanie danych w odpowiedzi:

<?php

/**
 * Add data to global context.
 *
 * @param string $name
 * @param mixed $value
 * @return mixed|array
 */
function global_js($name = null, $value = null)
{

    static $attached = false;
    static $variables = [];

    if (! $attached) {

        $provide = function () use (&$variables) {

            if (! empty($variables)) {

                echo("<script type=\"text/javascript\">\n\n");

                foreach ($variables as $name => $value) {

                    echo("    window['$name'] = JSON.parse('".json_encode($value)."');\n");
                    unset($variables[$name]);

                }

                echo("\n</script>\n");

            }

        };

        add_action('wp_print_scripts', $provide, 0);
        add_action('wp_print_footer_scripts', $provide, 0);

        $attached = true;

    }

    if (is_null($name) && is_null($value)) {
        return $variables;
    }

    return $variables[$name] = $value;

}

Dodaj niektóre dane JS do kontekstu okna:

<?php

global_js('fruits', ['apple', 'peach']);

// produces: `window['fruits'] = JSON.parse('["apple", "peach"]');`

Będzie to działać zarówno dla skryptów nagłówka, jak i skryptów stopki i nie będzie się powtarzać.

Erutan409
źródło