Как я могу заставить #evaluate помещать свои результаты в область страницы?

Я не могу заставить #evaluate установить переменную, используя какое-либо принятое решение, которое я видел для преобразования строки JSON в карту с использованием Velocity в Confluence.

У меня есть строка JSON из другой системы, которую я использую для генерации динамических данных. Во время разработки я смог работать с картой напрямую:

#set($textMapRaw = [{"ace":"clubs"}])

$textMapRaw.get(0).ace

Последняя строка отображается как «трефы».

Я ожидал использовать #evaluate, чтобы превратить живые данные в массив объектов. Однако кажется, что #evaluate не возвращает объявленную переменную в область видимости, когда я что-то с ней делаю. Вот та же карта, представленная в виде строки:

#set($textMapHtml = '[{"ace":"clubs"}]')
#set($evalHtml = '#set($myMapHtml = '+ $textMapHtml +')')
evalHtml = $evalHtml<br/>
#evaluate($evalHtml)

$myMapHtml.get(0).ace

Последняя строка отображается как «$myMapHtml.get(0).ace».

Я знаю, что $myMapHtml оценивается, потому что я получал оценочную трассировку стека, когда не добавлял Html в конец, чтобы избежать махинаций Confluence с автоматическим экранированием.

Я пробовал это с экранированием хэша в наборе, используя ${hash}set. Я пробовал одинарные кавычки и двойные кавычки. Я пробовал это, просто установив строку с помощью оценки:

#evaluate('#set($dippity = "doo")')
$dippity

#set($hash = '#')
#evaluate("${hash}set($blue = 'moon')")
$blue

Что бы я ни делал с любым ратифицированным кодом #evaluate, он никогда не оценивается в Confluence. Я всегда получаю результат, идентичный неопределенной переменной.

Примечание. В нашей среде я не могу найти обходной путь на Java и вставить его в шаблон. Мне нужно найти чистое решение в шаблоне.

Если я скопирую и вставлю ваш код в свою тестовую среду, используя Velocity 1.7 или 2.0, он будет работать... Какую версию Velocity вы используете?

Claude Brisson 09.04.2019 14:50

Вы делаете это в Confluence? Вот в чем хитрость. Я считаю, что Confluence 6.13 использует Velocity 1.6.4. Но, похоже, это проблема с Confluence.

Kevin 10.04.2019 15:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
262
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Velocity 1.6.4 не позволяет изменять контекст оценки из директивы #evaluate. Поэтому при использовании этой версии невозможно создавать записи контекста с динамическим именем.

Однако вы можете сохранить их на карте:

#set( $stringMap = '[{"ace":"clubs"}]' )

#set( $myMap = {} )
#set( $eval = '#set($list = ' + $stringMap + ') #set ($myMap.ace = 
$list.get(0).ace)' )
#evaluate( $eval )

$myMap.ace ## prints 'clubs'

В строке 2 есть ошибка, потому что вы не поместили одноразовую переменную для директивы set/put. Добавление этого и запуск кода не достигают цели превращения строки в повторяемый массив карт. значение HTML является строкой.

Kevin 10.04.2019 16:50

@Kevin - отредактировано в соответствии с вашими комментариями. Но, видя ваш ответ, очевидно, вы его поняли...

Claude Brisson 10.04.2019 23:04

Спасибо, что избавили меня от дальнейших попыток вернуть переменную в глобальную область видимости.

Kevin 11.04.2019 15:20
Ответ принят как подходящий

Поскольку кажется, что вы не можете вернуть переменную в текущую область, я нашел обходной путь. Просто используйте оценку, чтобы передать массив/карту в макрос.

Вы по-прежнему сталкиваетесь с проблемами области видимости, если пытаетесь манипулировать переменными за пределами вычисляемого кода или макроса, который он вызывает, но если вы будете осторожны, вы можете обойти это.

В моем случае я переместил еще один фрагмент кода внутрь макроса, чтобы воспользоваться преимуществами локальной области видимости и определить, сколько элементов было обработано.

#macro(processMap $theMap)
  #set($count = 0)
  #foreach($item in $theMap)
    #set($count = $velocityCount)
    <p>This thing is $item.tweedle</p>
  #end
  <p><b>I did that $count times</b></p>
#end

#set($workaroundHtml = '[{"tweedle":"dee"},{"tweedle":"dum"}]')

#set($eval = '#processMap(' + $workaroundHtml + ')')

#evaluate($eval)

Другие вопросы по теме