메서드에 인수로 전달되는 번역 가능한 문자열의 미리 서식이 지정된 텍스트로 JSON을 예쁘게 인쇄합니까?

Aug 21 2020

긴 프리앰블 :

서비스 클래스에서 특정 권한을 가진 사용자에 대한 화면 디버그 정보를 표시하고 싶습니다.

에서 my_custom_module.permissions.yml:

'view debug info':
  title: 'View debug info'
  description: 'Allow user to view DataPartner API debugging messages.'
  restrict access: true

에서 src/Api/DataPartner.php:

<?php

namespace Drupal\my_custom_module\Api;

/**
 * @file
 * Contains \Drupal\my_custom_module\Api\DataPartner.
 */

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Provides API integration methods.
 */
class DataPartner {

  use StringTranslationTrait;

  /**
   * Private function to determine whether displaying debug info is permitted.
   *
   * @return bool
   *   TRUE if debugging is permitted for current user in current environment.
   */
  private function hasDebugPermission() {
    return MY_CUSTOM_MODULE_DEBUG_FLAG && $this->account->hasPermission('view debug info');
  }

그것에 대해 조금 더 있습니다.

*.services.yml사용자 계정 권한 확인, 화면에 Drupal 메시지 작성 및 기타 작업을 처리하는 방법을 제공하기 위해 사용하고있는 Service 클래스 의 종속성 주입 항목은 생략했습니다 . (내가 주입하는 서비스를 보여주고 StringTranslationTrait내 질문과 관련된 경우 해당 종속성을 주입하는 대신 Service 클래스 에서을 사용하고 있음을 보여주기에 충분합니다 .)

또한 MY_CUSTOM_MODULE_DEBUG_FLAG프로덕션 환경에서 디버깅을 비활성화하고 ConfigForm의 확인란을 기반으로 토글 하는 상수 를 정의 했지만 실제 질문에는 영향을 미치지 않습니다.

어쨌든 이제 다음과 같은 API 디버깅 메시지를 표시 할 수 있습니다.

if ($this->hasDebugPermission()) {
  $this->messenger->addMessage($this->t('Step 2: $response = <br><pre>@value</pre>', [ '@value' => print_r(json_encode($this->response_decode, JSON_PRETTY_PRINT), TRUE),
  ]));
}

이것은 괜찮지 만 더 나은 캡슐화를 원했습니다. 나는 이것을 시도했다 :

  /**
   * Private function to display debug info if permitted.
   *
   * @param string $message * Translatable message string to be displayed, if permitted. * @param array $variables
   *   Values for substitution in translatable string.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) { $this->messenger->addMessage($this->t($message, $variables));
    }
  }

그러나 이것은 다음과 같은 이유로 Drupal 코딩 표준을 위반합니다.

경고 | t()가능한 경우 문자열 리터럴 만 전달해야 합니다.

여기에 흥미로운 논의가 있습니다 .

연결된 문제 대기열은 문자열을 메서드에 인수로 전달 하기 전에 번역 할 문자열을 표시 할 수 있다고 언급하므로 다음 과 같이 시도했습니다.

  /**
   * Private function to display debug info if permitted.
   *
   * @param string $message
   *   Translatable message string to be displayed, if permitted.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) { $this->messenger->addMessage($message));
    }
  }

이렇게하면 다음과 같은 API 디버깅 메시지를 표시해야합니다.

this->displayDebugInfo($this->t('Step 2: $response = <br><pre>@value</pre>', [ '@value' => print_r(json_encode($this->response_decode, JSON_PRETTY_PRINT), TRUE),
]));

이 긴 서문은 저에게 질문을 던집니다.

실제 질문 :

이러한 방식으로 번역 가능한 문자열을 메서드에 전달하면 HTML 마크 업이 화면에 인쇄되므로 예쁘게 인쇄 된 JSON을 미리 서식이 지정된 텍스트로 보는 대신 사용자가보기 흉한 텍스트와 마크 업을 볼 수 있습니다.

브라우저 개발 도구의 DOM 검사기에서 마크 업을 살펴보면 일반 마크 업처럼 보이지만 &lt;pre&gt;.

  • 마크 업이 브라우저에서 해석되지 않는 이유는 무엇입니까? (보안상의 이유가 있다고 가정합니다.)
  • 케이크 (예쁜 형식의 JSON을 미리 형식화 한 JSON $this->messenger->addMessage())를 사용하고 (더 나은 객체 지향 캡슐화로) 먹는 경우 원하는 것을 얻을 수있는 방법이 있습니까?

답변

2 imclean Aug 28 2020 at 03:40

가장 간단한 방법은 Markup 클래스를 직접 사용하는 것입니다. 이것은 코더 / phpcs를 기쁘게해야합니다. Core도이 작업을 수행합니다 .

<?php

namespace Drupal\my_custom_module\Api;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Provides API integration methods.
 */
class DataPartner {

  use StringTranslationTrait;

  /**
   * Private function to determine whether displaying debug info is permitted.
   *
   * @return bool
   *   TRUE if debugging is permitted for current user in current environment.
   */
  private function hasDebugPermission() {
    return MY_CUSTOM_MODULE_DEBUG_FLAG && $this->account->hasPermission('view debug info'); } /** * Private function to display debug info if permitted. * * @param string $message
   *   Translatable message string to be displayed, if permitted.
   */
  private function displayDebugInfo(string $message, array $variables = []) {
    if ($this->account->hasPermission('view debug info')) { $this->messenger->addMessage(Markup::create($message)));
    }
  }

}

@file 네임 스페이스가 지정된 클래스에는 필요하지 않습니다.