Problems with render inside macros

Hello!

I have problems with render inside my new macros:

I have code:

return Arrays.asList(
                new ParagraphBlock(Collections.singletonList(
                        new RawBlock(content, new Syntax(MARKDOWN, "1.2"))))
        );

But it’s show nothing with all type of sintax except HTML_4;

If on page with macros change syntax in information
image
From xwiki 2.1 to smth else and back - content will be shown, but if reload page - dissapeare again;

Help :frowning:
Need to show text im Markdwon 1.2 inside macros;

I tried to make in such way

Map<String, String> params = new HashMap<>();
        params.put("syntax", parameters.getStyle());

        return Collections.singletonList(
                new ParagraphBlock(Collections.singletonList(
                        new MacroBlock("content", params, content, false)))
        );

but have the same result

I think you might have misunderstood the use of raw blocks. The purpose of raw blocks is to output raw content that will be output as-is in the respective target syntax. In other target syntaxes, the raw block is normally ignored. This makes most sense with HTML raw blocks as rendering usually targets HTML but could also be used with the LaTeX blocks and the LaTeX export.

In your second example, I don’t understand why you set the “inline” parameter of the “content” macro to false but wrap it in a paragraph which expects inline content. What’s the content of the “style” parameter in the second example?

I think it would help if you could explain what you actually want to do.

Hello!
Thanks for response.
I want to display markdown/1.2 text from received from git on page.
I changed inLine to true; but nothing changed, behavior stay the same

Value parameter style is “markdown/1.2”

I’ve changed cod to

Map<String, String> params = new HashMap<>();
        params.put("syntax", parameters.getStyle());

        return Collections.singletonList(new MacroBlock("content", params, content, true));

But the same result

Do you want to display the markdown code as-is or do you want to have it parsed and rendered as HTML?

Just as is; display as markdown;

If you still want to display it as plain text, i.e., with line breaks preserved and possible HTML tags not interpreted, I would suggest to parse the content as plain text and then add the resulting blocks to the returned blocks. For this, you can use a plain text parser:

    @Inject
    @Named("plain/1.0")
    private Parser plainTextParser;

and then you can write

        String markdownContent = "This is a **bold** text.\n\nWith line breaks.";

        XDOM xdom;
        try {
            xdom = this.plainTextParser.parse(new StringReader(markdownContent));
        } catch (ParseException e) {
            throw new MacroExecutionException("Failed to parse the content", e);
        }

        return xdom.getChildren();

The plain text parser already wraps the content in a paragraph, so no need to wrap it yourself. I hope this helps, let me know if I misunderstood something.

Michael

this code

@Inject
    @Named("plain/1.0")
    private Parser plainTextParser;

    @Override
    public List<Block> display(String content, GitLabMacroParameters parameters) throws MacroExecutionException {
        XDOM xdom;
        try {
            xdom = this.plainTextParser.parse(new StringReader(content));
        } catch (ParseException e) {
            throw new MacroExecutionException("Failed to parse the content", e);
        }
        return Collections.singletonList(xdom);
    }

return such error

java.lang.NullPointerException
at org.xwiki.contrib.gitLab.macro.internal.displayer.StyledGitLabDisplayer.display(StyledGitLabDisplayer.java:71)
at org.xwiki.contrib.gitLab.macro.internal.GitLabMacro.execute(GitLabMacro.java:89)
at org.xwiki.contrib.gitLab.config.internal.AsyncGitLabMacro.executeCodeMacro(AsyncGitLabMacro.java:98)
at org.xwiki.contrib.gitLab.config.internal.GitLabBlockAsyncRenderer.execute(GitLabBlockAsyncRenderer.java:120)
at org.xwiki.rendering.async.internal.block.AbstractBlockAsyncRenderer.render(AbstractBlockAsyncRenderer.java:157)
at org.xwiki.rendering.async.internal.block.AbstractBlockAsyncRenderer.render(AbstractBlockAsyncRenderer.java:54)
at org.xwiki.rendering.async.internal.AsyncRendererJob.runInternal(AsyncRendererJob.java:101)
at org.xwiki.job.AbstractJob.runInContext(AbstractJob.java:246)
at org.xwiki.job.AbstractJob.run(AbstractJob.java:223)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)

What line is the null pointer exception from in that code? That code doesn’t look like a macro. Is it possible that your StyledGitLabDisplayer is not a component? If so, either consider making it a component so you can inject the plain text parser or pass the plain text parser as parameter.

Sorry for very much questions.
in this line

 xdom = this.plainTextParser.parse(new StringReader(content));

but I think it’s component or how to make it component?

It’s just a class inside macro package

image

To be a component, the class needs to be annotated accordingly. I think it might not be a component or not loaded through the component manager (e.g., by injecting it in another class) because that would explain why this.plainTextParser is null (the most likely reason for the exception you’re seeing). Injecting other components works only in components as the injection is done by the component manager.

Yes, you’re rigth!
I replaces calling

this.componentManager.getInstance(GitLabDisplayer.class, parameters.getStyle());

with creating object of class;

I return using this.componentManager.getInstance

Now it’s worling correctly.
Thanks a lot!!!

But if I wnt to use macro block inside with user syntax (user select in macro)
Is it possible to use

MacroBlock("content", params, content, true)

?

I need it because file content is in GitHub-Flavored CommonMark 1.0
with images and i want to display them too;

If use your variant
image

But I need to display
image

You said you wanted to display the markdown as-is, that’s why I provided you with instructions to display the markdown as-is and not rendered. If you want to display it rendered as HTML, you could try replacing

    @Inject
    @Named("plain/1.0")
    private Parser plainTextParser;

by

    @Inject
    @Named("markdown+github/1.0")
    private Parser plainTextParser;

Of course you could/should also rename the variable to something like markdownParser to make the code clearer. If you’re using a recent-enough XWiki version (14.10.5/15.1), you could also use a MacroContentParser which provides some more convenience features. Further, if you’re on 14.2 or more recent, you could also pass an id generator to the parse method to ensure that ids, e.g., of headings, are unique across the whole document. You can get the id generator using macroContext.getXDOM().getIdGenerator() where macroContext is the context parameter of type MacroTransformationContext that is passed to the execute-method of the macro.

The MacroBlock for the content macro might work, too, though you should definitely set the inline parameter to false if this should be a whole document.

Hello!

Thanks a lot!
I have error

Failed to execute the GitLab macro. Причина: [Can't find descriptor for the component with type [interface org.xwiki.rendering.macro.MacroContentParser] and hint [markdown+github/1.0]]

I tink that is bacouse I don’t have any dependency?
image

No, org.xwiki.rendering.macro.MacroContentParser doesn’t have a concrete syntax as hint. Instead, you need to omit the name and pass the syntax to the parse method. See here for the method definition. As I’ve said, it’s only available in recent versions of XWiki, otherwise you’ll need to directly use the parser as shown in my example. The advantage of MacroContentParser.java is that it automatically passes the id generator to the parser and can execute transformations like macros. I haven’t checked but it seems like Markdown supports macros. If you don’t absolutely trust the content you’re rendering, you should enable restricted mode for the transformations. See also the documentation on macros.

Have you first tried the exact code in my example?

Thanks a lot!

finaly work for my

public class MarkdownGitLabDisplayer extends AbstractGitLabDisplayer
{
    @Inject
    private MacroContentParser macroContentParser;

    @Override
    public List<Block> display(String content, GitLabMacroParameters parameters, MacroTransformationContext context) throws MacroExecutionException {
        XDOM xdom = this.macroContentParser.parse(content, new Syntax(SyntaxType.MARKDOWN, "1.2"), context,
                true, MetaData.EMPTY, false);
        return Collections.singletonList(xdom);
    }
}


Sory for long answer - I was on vacation.

1 Like