Jump to content
Wanze

Module: Twig for the TemplateEngineFactory

Recommended Posts

26 minutes ago, gmclelland said:

I read up on latte and liked it, but Twig is so widely used in other CMS systems like Grav, Drupal 8, CraftCms, Bolt.Cm and others.  It seemed better to invest my time learning something a bit more portable.

I see your points, been there too, then went back to latte because of the same issues you mentioned. But of course it was easier for me because I was already familiar with latte.

Share this post


Link to post
Share on other sites
On 12/25/2016 at 8:40 AM, gmclelland said:

I also like the Tracy debugger module. I haven't tried yet, but I wonder if that can be used with twig somehow?

I am not a twig or latte user, but if you figure out some changes to Tracy that are needed to work well with these, please let me know - happy to help support them. I would expect there is an easy way with latte given that they are both by the Nette guys.

Share this post


Link to post
Share on other sites

No issues with latte, but usually I call Tracy from PHP files.

Share this post


Link to post
Share on other sites

I'm trying to attach the hook initTwig into the template (_init.php), but it doesn't work.

wire()->addHookAfter("TemplateEngineTwig::initTwig", function(HookEvent $event) {
  $twig = $event->arguments('twig');
  // Extend $twig with custom code
});

 

By now, I'm able to hook it correctly only by hooking within a class (for example a class defined in a module), but sometimes it's useful to extend it directly from a template without the hassle of dealing with a module.

Anyone experiencing the same issue?
Thanks!

Share this post


Link to post
Share on other sites

@Basilico Agency I have exactly the same code and I am able to extend twig. For example with this code you can enable debugging
 

wire()->addHookAfter("TemplateEngineTwig::initTwig", function($event) {
  $twig = $event->arguments('twig');
  $twig->addGlobal('hsaApp', wire('config')->hsaApp);
  $twig->addGlobal('hsaDist', wire('config')->hsaDist);
  $twig->addExtension(new \Twig_Extension_Debug());
});

 

Share this post


Link to post
Share on other sites

I am having difficulty debugging variables within twig. Do I need to do it in PHP side instead?
Everytime I try to dump something that isn't a very simple string or small array, I get a blank page. Is there any tip for debugging variables correctly?

Here's a simple example (in a multilang website) where I get a blank page:

{% for lang in languages %}
  {{ dump(lang) }}
{% endfor %}

 

Share this post


Link to post
Share on other sites

@gmclelland I already have dump enabled, the problem is that I get a blank page when I output something, it seems that it is trying to return an object that is too big. With PHP I have a easier time debugging the code, but don't know how to debug even from there, when twig is enabled.

Share this post


Link to post
Share on other sites
On 18.2.2017 at 6:42 PM, microcipcip said:

I am having difficulty debugging variables within twig. Do I need to do it in PHP side instead?
Everytime I try to dump something that isn't a very simple string or small array, I get a blank page. Is there any tip for debugging variables correctly?

Here's a simple example (in a multilang website) where I get a blank page:


{% for lang in languages %}
  {{ dump(lang) }}
{% endfor %}

 

@microcipcip 

I suggest to debug your variables/code on the PHP site, not in twig. All the variables that are available in twig are passed from your controller and they are available there too. In your example, you try to dump multiple Language objects, I also guess that this is too much to handle for twig. The 'languages' variable corresponds to the ProccessWire $languages API variable, so you could var_dump() a language object in your controller.

In general: Twig should only be used to organize your markup and display variables. If twig templates contain more complex logic code, this should be moved to the controller or a module/class, depending on how you organize your code.

Cheers

Share this post


Link to post
Share on other sites

@Wanze Ok I understand! Last question (hopefully), if I have a home.php and home.twig file, and in the home.php I try to echo something, for example `echo $page->title`, in the frontend I don't see anything, I have to add `exit();`. Is this the correct way of debugging with php?

Share this post


Link to post
Share on other sites

The echo/var_dump in combination with die() or exit() is a quick and simple way of doing it. You can check out the TracyDebugger module. A more sophisticated solution would be to use an IDE for development, for example PHPStorm, which offers to debug with breakpoints, in combination with xdebug. However, the setup is not thaat easy ;)

Share this post


Link to post
Share on other sites

Hi @Wanze, any idea why I can't do this in my twig templates?

{{ config.urls.root }}

or 

// with TracyDebugger installed
{{ bd(config.urls.root) }}

Both of these result in errors.

Exception: An exception has been thrown during the rendering of a template ("Method Paths::root does not exist or is not callable in this context") in "basic-page.twig" at line 4.

I have this option checked.

58af08c9213ae_ModulesProcessWirepwtwig.dev2017-02-2310-06-57.jpg.efc706d852afef7c88ec966152dc250a.jpg

Share this post


Link to post
Share on other sites

@gmclelland

Regarding the error when using tracy in twig: I think that the function "bd" is not available in twig. You can't use any global functions from PHP, they are wrapped by registered functions in the twig environment. After all, twig should just be used to present stuff. Though @jmartsch mentioned that it works, so I'm not sure. I guess that you would need to register a custom function to twig, via hook, which wraps around "bd". But I suggest to debug your application/variables on the PHP site instead of twig templates.

Share this post


Link to post
Share on other sites

Perhaps this could work in twig templates too - in ready.php add this:

$view->bd = function($data) {
	bd($data);
};

then use this in twig files:

{{ $bd('hello world') }}

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @jmartsch, @Wanze, and @tpr.

I tried this and it works:

{{ config.httpHost }}

So I know TemplateEnfineTwig and TemplateEngineFactory modules are passing the config variable correctly into the twig template.

@jmartsch said that it no longer exists.  I wonder why $config->urls->root is still listed on https://processwire.com/api/variables/config/.  It also works in my template file basic-page.php if I set it to variable and then pass it to the view, just not in my basic-page.twig file.

I did a bd( $config->urls->root ) in my basic-page.php and it returns "/"

I also did a bd ($config->urls); in my basic-page.php and I did notice _root = "/".  Maybe the underscore prefix means it is private, which is why it bombs out when {{ config.urls.root }} ?

Share this post


Link to post
Share on other sites

@gmclelland

Which version of ProcessWire are you using? I checked the Config class, more detailed this line: https://github.com/processwire/processwire/blob/master/wire/core/Config.php#L186

What happens if you do: {{ config.urls('root') }} ?

ProcessWire often makes use of PHP's magic methods, I remember to read somewhere that Twig may have a problem with this because the dot is used to access both properties and methods of an object.

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, Sephiroth said:

After picking up Symfony, I think i might migrate my PW from Smarty to Twig, 

Could you explain the reason? I'm interested because I know smarty from earlier and didn't use twig so far, my impression is that they are both similar in most areas. Good thing about using the template engine factory is that you can now replace your smarty templates with twig templates, without touching any code in the controllers :) 

Share this post


Link to post
Share on other sites
18 hours ago, Wanze said:

Could you explain the reason? I'm interested because I know smarty from earlier and didn't use twig so far, my impression is that they are both similar in most areas. Good thing about using the template engine factory is that you can now replace your smarty templates with twig templates, without touching any code in the controllers :) 

The major difference for me is the how detailed it is for me to write Twig Extensions, especially in OOP manner asides that they are quite similar. 

  • Like 1

Share this post


Link to post
Share on other sites

@Wanze I am trying to build a simple contact form with Twig but I am unable to do an ajax request to the php template file. My template name is test.php and I have the following code:

<form class="form" action="./" gy="g">
	<label for="first_name">Name</label>
	<input name="first_name" id="first_name" type="text" required="">

	<label for="email">Email</label>
	<input name="email" id="email" type="email" required="">

	<label for="msg">Msg</label>
	<textarea name="msg" id="msg" cols="30" rows="10" required=""></textarea>

	<input type="hidden" value="{{ page.title }}">
	<button>Send</button>
</form>
// ajax submit
$form.submit(function (e) {
  var request = $.ajax({
    url: $form.attr('action'),
    method: 'POST',
    data: $form.serialize(),
    dataType: "html"
  });

  request.done(function( data ) {
    console.log(data);
  });

  request.fail(function( jqXHR, textStatus ) {
    alert( "Request failed: " + textStatus );
  });

  // avoid to execute the actual submit of the form.
  e.preventDefault();
});

In test.php I tried:

if (wire('input')->post) {
  echo "Submitted";
  // with this I get echo back in the AJAX response, but if I refresh the page I get a blank page with the text "Submitted" in it.
  exit();
}

if (wire('input')->post->submit) {
  echo "Submitted";
  // this never get fired
  exit();
}

// here twig code...
$test = wire('page')->siblings("template=test");
$view->set('test', $test);

 

Share this post


Link to post
Share on other sites

There are several problems in your code:

wire('input')->post always returns true, so you can't use this check.

wire('input')->post->submit only returns true, if your POST data contains an element having "submit" as name, I can't see this in your form. So you could add a hidden element like this:

<input type="hidden" value="1" name="submit">

Also your hidden element containing the page title as value is missing a name attribute :)

Hope it helps!

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...