Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables in blocks #1390

Open
1 of 2 tasks
DIDoS opened this issue May 30, 2018 · 8 comments
Open
1 of 2 tasks

Variables in blocks #1390

DIDoS opened this issue May 30, 2018 · 8 comments

Comments

@DIDoS
Copy link

DIDoS commented May 30, 2018

This is:

  • a bug report
  • a feature request

Expected Behavior

Being able to create a block with an array of variables (aka foreach in templating).

In the docx "template":

Guests:
${CLONEME}
Forname: ${FORENAME}
Lastname: ${LASTNAME}
${/CLONEME}

In the code:

$templateProcessor->cloneBlock('CLONEME', [
['FORENAME' => 'John', 'LASTNAME' => 'Donut'],
['FORENAME' => 'Cat', 'LASTNAME' => 'Stefano']
]);

I want to start a discussion about this before I might implement it and send a PR.

@rkorebrits
Copy link

Why don't you just loop through the array and set the values?

@DIDoS
Copy link
Author

DIDoS commented May 31, 2018

Well this way I can have the formatting and text in the template and fill the data in the code. I don't see how this would be possible. Especially with two times the same macro FORENAME and two times LASTNAME.
The result of the code above is:

Forname: John
Lastname: Donut
Forname: Cat
Lastname: Stefano

How would you achieve that with a foreach loop?

@rkorebrits
Copy link

rkorebrits commented May 31, 2018

When using setValue, you use a third parameter and set it to 1

            $templateProcessor->setValue(
                'FORENAME', $forename, 1
            );

That way it will only replace the first value it finds. So first you use cloneBlock and clone the blocks, and after that run your foreach and only replace the first variable at a time.

@DIDoS
Copy link
Author

DIDoS commented Jun 1, 2018

If anybody else is wondering how to do this:

        $repeatdata = [
            ['FORENAME' => 'John', 'LASTNAME' => 'Donut'],
            ['FORENAME' => 'Cat', 'LASTNAME' => 'Stefano']
        ];
        $templateProcessor->cloneBlock('CLONEME', count($repeatdata));

        foreach ($repeatdata as $repeatitem){
            foreach ($repeatitem as $search => $replace){
                $templateProcessor->setValue($search, $replace, 1);
            }
        }

Thanks @rkorebrits! This is way cleaner.

@rkorebrits
Copy link

Perfect, that's pretty much how I use it also (although without the second foreach, but assign one by one). Also prefer it like this without preparing the data as it's cleaner to have conditional logic in the foreach imho.

Please close the ticket if resolved :-)

@DIDoS DIDoS closed this as completed Jun 1, 2018
@DIDoS
Copy link
Author

DIDoS commented Jul 17, 2018

I found two edge-cases where the solution above does not work (but with my PR):

  1. If you have two Blocks with the same (named) macros inside:
${MYCAT}
Name: ${NAME}
${/MYCAT}
${MYDOG}
Name: ${NAME}
${/MYDOG}

This only works accidentally if the data is in the correct order (CAT before DOG). Otherwise Cat will be replaced with dogs name since the block context is missing,

  1. If you have a macro (with the same name) twice in the Block:
${MYCAT}
Her name is "${NAME}". ${NAME} is the best cat in the world,
${/MYCAT}

Obviously only the first one is being replaced.

@DIDoS DIDoS reopened this Jul 17, 2018
@rkorebrits
Copy link

  1. Is a good point, 1. Is just bad (ambiguous) naming imho. Rather call it CAT_NAME and DOG_NAME

@DIDoS
Copy link
Author

DIDoS commented Jul 17, 2018

In a path syntax the CAT.NAME and DOG.NAME makes sense. Yes, the second is worse and I don't even have a workaround for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants