What is correct way to get block strings now? #650
-
Hi. Previously in my block renderer, I was using I use this to get content on my block, which also has: public function canContain(AbstractBlock $block): bool {
return FALSE;
} in element definition. I'm 100% sure there will be only string inside a block, and now I can't access it. This is what I get in Why does it in "next" Paragraph, and sometimes in Heading. SourceElement<?php
namespace Drupal\druki_parser\CommonMark\Block\Element;
use League\CommonMark\Block\Element\AbstractBlock;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
use League\CommonMark\Util\RegexHelper;
/**
* Class MetaInformationElement
*
* @package Drupal\druki_parser\Plugin\Markdown\Extension
*/
class MetaInformationElement extends AbstractBlock {
/**
* Indicates is meta information closing block found.
*
* @var bool
*/
protected $isCloserFound;
/**
* MetaInformation constructor.
*/
public function __construct() {
$this->isCloserFound = FALSE;
}
/**
* {@inheritdoc}
*/
public function canContain(AbstractBlock $block): bool {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function acceptsLines(): bool {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function isCode(): bool {
// @todo Avoid it. Not sure this is good approach, but only working with
// matches. Try some workaround with $context->advanceBy(-3) in
// handleRemainingContents(). This will let condition pass. But need some
// extra fixes, since this not fix all the problems that fix this value.
return TRUE;
}
/**
* {@inheritdoc}
*/
public function shouldLastLineBeBlank(Cursor $cursor, $currentLineNumber): bool {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function matchesNextLine(Cursor $cursor): bool {
if ($this->isCloserFound()) {
return FALSE;
}
return TRUE;
}
/**
* @return bool
*/
public function isCloserFound(): bool {
return $this->isCloserFound;
}
/**
* @param bool $isCloserFound
*/
public function setIsCloserFound($status): void {
$this->isCloserFound = $status;
}
/**
* {@inheritdoc}
*/
public function handleRemainingContents(ContextInterface $context, Cursor $cursor): void {
if ($cursor->getNextNonSpaceCharacter() == '-') {
$match = RegexHelper::matchAll('/^\-{3}$/', $cursor->getLine(), $cursor->getNextNonSpacePosition());
if (!empty($match)) {
$this->setIsCloserFound(TRUE);
return;
}
}
$context->getTip()->addLine($cursor->getRemainder());
}
} Parser<?php
namespace Drupal\druki_parser\CommonMark\Block\Parser;
use Drupal\druki_parser\CommonMark\Block\Element\MetaInformationElement;
use League\CommonMark\Block\Parser\BlockParserInterface;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
/**
* Class MetaInformationParser
*
* @package Drupal\druki_parser\CommonMark\Block\Parser
*/
class MetaInformationParser implements BlockParserInterface {
/**
* {@inheritdoc}
*/
public function parse(ContextInterface $context, Cursor $cursor): bool {
// Only works for metadata found at the beginning of the file. Other "---"
// will be replaced as expected with "<hr />".
if ($context->getLineNumber() > 1) {
return FALSE;
}
if ($cursor->isIndented()) {
return FALSE;
}
$meta_information = $cursor->match("/^\-{3}$/");
if (!$meta_information) {
return FALSE;
}
$context->addBlock(new MetaInformationElement());
return TRUE;
}
} Renderer<?php
namespace Drupal\druki_parser\CommonMark\Block\Renderer;
use Drupal\Core\Serialization\Yaml;
use League\CommonMark\Block\Element\AbstractBlock;
use League\CommonMark\Block\Renderer\BlockRendererInterface;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
/**
* Class MetaInformationRenderer
*
* @package Drupal\druki_parser\CommonMark\Renderer
*/
class MetaInformationRenderer implements BlockRendererInterface {
/**
* {@inheritdoc}
*/
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = FALSE): HtmlElement {
$strings = $block->getStrings();
$content = [];
$yaml_string = implode($strings, PHP_EOL);
$yaml_array = Yaml::decode($yaml_string);
foreach ($yaml_array as $key => $value) {
$content[] = new HtmlElement('div', [
'data-druki-key' => $key,
'data-druki-value' => is_array($value) ? implode(', ', $value) : $value,
]);
}
return new HtmlElement('div', ['data-druki-meta' => ''], $content);
}
} Content example---
id: route-access-control
title: Контроль доступа
path: /docs/8/routing/access-control
core: 8
category-area: Маршрутизация
category-order: 4
search-keywords:
- доступ защита маршрутов контроллеров права доступа
--- Can you point me in the right direction? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
My apologies, it looks like I forgot to document this change. I will fix this ASAP. Basically, you'll want to make these changes:
|
Beta Was this translation helpful? Give feedback.
-
Thank you for the fast response. I'll check it and reply again. 👍 |
Beta Was this translation helpful? Give feedback.
-
Fixed it! Thanks. I have another question since I asked already. In my element (same example) I need to set For example, we have content to parse:
With
So, this is parsed correctly. Especially array. But when I set
As you can see, YAML array is missing. I think this is parsed something like lists, but don't know why, because I still have I can't understand the difference. Need I fix it, or my "hack" is good solution? |
Beta Was this translation helpful? Give feedback.
-
Perhaps a better name for Because this type of greedy behavior mostly belongs to code elements, we call it |
Beta Was this translation helpful? Give feedback.
-
Additional documentation has been added :) I'm going to close this for now, but let me know if you have any further questions I can assist with! |
Beta Was this translation helpful? Give feedback.
-
Thank you again. Now I understand what |
Beta Was this translation helpful? Give feedback.
My apologies, it looks like I forgot to document this change. I will fix this ASAP.
Basically, you'll want to make these changes:
MetaInformationElement
class extend fromAbstractStringContainerBlock
instead ofAbstractBlock
finalize()
method to set the final contents like$this->finalStringContents = implode("\n", $this->strings);
getStringContent()
method in your renderer to get those finalized string contents