За последние 24 часа нас посетили 17552 программиста и 1720 роботов. Сейчас ищут 1713 программистов ...

shortcode и данные из массива перебором

Тема в разделе "Wordpress", создана пользователем spiritus_infernus, 23 ноя 2016.

  1. spiritus_infernus

    spiritus_infernus Новичок

    С нами с:
    14 май 2016
    Сообщения:
    14
    Симпатии:
    0
    Привет всем.
    Хотел бы попросить подсказку, как можно получить данные из цикла за пределами шорткода в тело этого самого шорткода. Пока делается так:
    PHP:
    1. $val1= get_post_meta( $post->ID, 'val1', true);
    2. $val2 = get_post_meta( $post->ID, 'val2', true);
    3. $val3= get_post_meta( $post->ID, 'val3', true);
    4. $val4= get_post_meta( $post->ID, 'val4', true);
    5. function the_placemarks()
    6. {
    7. for ($ii = 0; $i < count($val1);$i++){
    8. $out[$i] = "[placemark='{$val1[$i]}' header='{$val2[$i]}'  body='{$val1[$i]}','{$val3[$i]}' footer=<a  href='{$val4[$i]}'>'{$val4[$i]}'</a> /]";
    9. };
    10. return $out;
    11. };
    12. the_placemarks();
    13. echo do_shortcode('[showyamap]'.the_placemarks().'[/showyamap]');
    Результаты данная конструкция не отдаёт. Используется для управляемой генерации точек на карте с использованием плагина. Можно пойти альтернативным путём, а именно запихивать все значения, генерируемые в админке в отдельный метабокс, который можно вывести через отдельное поле, но хотелось бы достичь результата в текущем варианте. Ткните носом, где не вижу ошибку.
    Спасибо заранее.
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    1. Зачем вызывать the_placemarks() два раза? Второго достаточно должно быть
    2. Внутри the_placemarks() не откуда взяться переменным $val* https://secure.php.net/manual/ru/language.variables.scope.php передавай в аргументах https://secure.php.net/manual/ru/functions.arguments.php
    3. Там в for, для чего $ii? Вроде должно быть $i https://secure.php.net/manual/ru/control-structures.for.php
    4. Для отладки делал например var_dump(the_placemarks()) чтобы убедиться что она возвращает нужные данные?
    5. Функция the_placemarks() как я вижу возвращает массив https://secure.php.net/manual/ru/language.types.array.php а потом ты его пытаешься вывести через echo, не выйдет, надо по очереди вывести каждый ключ массива или склеить в строку с помощью https://secure.php.net/manual/ru/function.implode.php
    6. Отступы в коде использую, чтобы было красиво, http://svyatoslav.biz/misc/psr_translation/
     
    spiritus_infernus нравится это.
  3. spiritus_infernus

    spiritus_infernus Новичок

    С нами с:
    14 май 2016
    Сообщения:
    14
    Симпатии:
    0
    Привет, спасибо за оперативность.
    Утром был сонный, предоставил частично некорректный код, за что и извиняюсь. На самом код я использую вот такой:
    PHP:
    1. $val1= get_post_meta( $post->ID, 'val1', true);
    2. $val2 = get_post_meta( $post->ID, 'val2', true);
    3. $val3= get_post_meta( $post->ID, 'val3', true);
    4. $val4= get_post_meta( $post->ID, 'val4', true);
    5. function the_placemarks()
    6. {
    7.     for ($i = 0; $i < count($val1);$i++){
    8.         $out[$i] = "[placemark='{$val1[$i]}' header='{$val2[$i]}'  body='{$val1[$i]}','{$val3[$i]}' footer=<a  href='{$val4[$i]}'>'{$val4[$i]}'</a> /]";
    9.     };
    10.     return $out;
    11. };
    12. echo do_shortcode('[showyamap]'.the_placemarks().'[/showyamap]');
    Соответственно, пункты 1 и 3 верны.
    2. Данные должны бы писаться пользователем в админке в специально отведённые метаполя, которые можно получать в фронтэнде двумя способами - через собственную функцию rwmb_meta ('val1') или через get_post_meta($post->ID,'val1',true); для более точной работы с массивами ( а эти конкретно данные в админке становятся массивами, что подтверждается дампом их на страницу: array(2) { [0]=> string(44) "Таганрог, 9-й переулок, 3А" [1]=> string(34) "Москва, Шолохова, 12" } ) используется последний метод.
    4. placemarks пытался через for выводить - данные не даёт. через дамп возвращает NULL. видимо в самой функции и есть проблема.
    5. Была идея склеить массивы, но склеивать 4 сразу я пока не умею.
    6. Понял, извиняюсь.
    UPD:
    В конечном итоге вот такой шорткод
    PHP:
    1. echo do_shortcode('[placemark address="Москва, Люблинская улица, 125" coordinates="55.673483,37.740749" header="Заголовок" body="контент" footer="подвал"/]');
    работает, но хотелось бы иметь возможность ставить эти самые placemark более управляемо
     
    #3 spiritus_infernus, 23 ноя 2016
    Последнее редактирование: 23 ноя 2016
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    про область видимости переменных не понятно?
    как использовать implode не понятно?
    --- Добавлено ---
    PHP:
    1. $arr = [
    2.     '[placemark...]',
    3.     '[placemark...]',
    4.     '[placemark...]',
    5. ];
    6. echo implode(PHP_EOL, $arr);
     
    spiritus_infernus нравится это.
  5. spiritus_infernus

    spiritus_infernus Новичок

    С нами с:
    14 май 2016
    Сообщения:
    14
    Симпатии:
    0
    В принципе да, раньше я с этим не сталкивался, поэтому это было в новинку. Изучил.
    Решил переписать почти всю процедуру вывода, проблема также изменилась:

    PHP:
    1. //              создаём отдельный класс для меток
    2.             class placemark {
    3.                 public $placeholder;
    4.                 public $placeholder_name;
    5.                 public $placeholder_phone;
    6.                 public $placeholder_link;
    7. //                  создаём конструктор
    8.                 public function __construct($placeholder, $placeholder_name, $placeholder_phone, $placeholder_link) {
    9.                       $this->placeholder = $placeholder;
    10.                       $this->placeholder_name = $placeholder_name;
    11.                       $this->placeholder_phone = $placeholder_phone;
    12.                       $this->placeholder_link = $placeholder_link;
    13.                 }
    14. //                  создаём возвращающую функцию
    15.                 public function place_mark() {
    16.                         return '[placemark address="'.$this->placeholder.'" header="'.$this->placeholder_name.'" body="'.$this->placeholder_phone.'" footer="'.$this->placeholder_link.'"/]';
    17.                     }
    18.                 }
    19. //              забираем переменные в виде массивов (на это указывает true в конце) из метаполей
    20.         $map_placeholder = get_post_meta( $post->ID, 'map_placeholder', true);
    21.         $map_placeholder_name = get_post_meta( $post->ID, 'map_placeholder_name', true);
    22.         $map_placeholder_phone = get_post_meta( $post->ID, 'map_placeholder_phone', true);
    23.         $map_placeholder_link = get_post_meta( $post->ID, 'map_placeholder_link', true);
    24.  
    25. //              генерируем вывод меток
    26.             function the_placemarks($map_placeholder, $map_placeholder_name, $map_placeholder_phone, $map_placeholder_link) {
    27.                 $arr_len = count($map_placeholder);
    28.             for($i = 0; $i < $arr_len; $i++){
    29.                 $mark[$i] = new placemark( $map_placeholder[$i], $map_placeholder_name[$i], $map_placeholder_phone[$i], $map_placeholder_link[$i] );
    30.                 return $mark[$i]->place_mark();
    31.             }
    32.             };
    33.         echo do_shortcode('[showyamap]'.the_placemarks($map_placeholder, $map_placeholder_name, $map_placeholder_phone, $map_placeholder_link).'[/showyamap]');
    Дамп вывода функции возвращает только первую метку:
    PHP:
    1. var_dump(the_placemarks($map_placeholder, $map_placeholder_name, $map_placeholder_phone, $map_placeholder_link));
    Код (Text):
    1.  
    2. string(143) "[placemark address="Москва" header="Название" body="+7999999999999" footer="http://example.org"/]"
    однако, если в функции the_placemarks return $mark[$i] заменить на echo дамп будет уже другим:
    [placemark address="Москва" header="Название" body="+7999999999999" footer="http://example.org"/][placemark address="Химки" header="Название 2" body="+7999999999998" footer="http://example.org"/][placemark address="Тверь" header="Название 3" body="+7999999999997" footer="http://example.org"/]NULL

    Почти таким, каким нужно, кроме NULL на конце и неработающей карты, конечно. Подскажите, как это можно исправить?
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    return делает выход из функции, и цикл for прерывается https://secure.php.net/manual/ru/function.return.php

    Можно результат в переменную собирать и после цикла вернуть результат из функции, примерно так:
    Что в коде значит .= https://secure.php.net/manual/ru/language.operators.string.php
    PHP:
    1. $buff = '';
    2.             for($i = 0; $i < $arr_len; $i++){
    3.                 $mark[$i] = new placemark( $map_placeholder[$i], $map_placeholder_name[$i], $map_placeholder_phone[$i], $map_placeholder_link[$i] );
    4.                 $buff .= $mark[$i]->place_mark();
    5.             }
    6. return $buff;
     
    spiritus_infernus нравится это.
  7. spiritus_infernus

    spiritus_infernus Новичок

    С нами с:
    14 май 2016
    Сообщения:
    14
    Симпатии:
    0
    Всё гениальное просто, спасибо за верное решение и за то, что помогли узнать больше.