2

I'm trying to utilize a node js package called can-compile which reads the contents from an ejs file and then converts the data to a usable and canjs friendly output. I'm trying to avoid saving the template data to a file on the server and using said file to convert the template data. That is where I have been trying to use php's STDIN/OUT.

The compiler takes the name of the template file as a parameter to read from. I've tried various methods of passing the template data to node command line with no success.

Ultimately what I'm trying to achieve is being able to send the uncompiled template data to the STDIN/OUT pipe and have it return the compiled code from the can-compile node package.

Can someone please point me in the right direction of what I should be doing. Here I'm using a small template example (see $input). But the template sizes vary up to hundreds of lines and characters.

$template_name = 'template_'.$template_data['name'].'.ejs';
$can_compiler = "/node_modules/can-compile/bin/can-compile --can 1.1.5 $template_name";
$input = "<img src="/media/<%==category.attrs.image%>" style="width:100%; height:100%;" />";
$cmd = sprintf("node %s",$can_compiler);

$descriptorspec = array(
    0 => array('pipe','r'), 
    1 => array('pipe','w'),
    2 => array('pipe','w')
);

$process = proc_open($cmd, $descriptorspec, $pipes);

if (is_resource($process)) {
    fwrite($pipes[0], $input);
    fclose($pipes[0]);

    $template_content = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $error_content = stream_get_contents($pipes[2]);
    fclose($pipes[2]);


    $return_value = proc_close($process);

    return $template_content;
}

I've already search through stack-overflow and found this How to pass variables as stdin into command line from PHP. The strange issue I'm running into is that my code has worked yesterday but not today. Maybe a fresh set of eyes can help me out.

Community
  • 1
  • 1
NoToBagels
  • 152
  • 1
  • 8
  • Off the top of my head I'm not really sure how PHP's `proc_open` behaves when you don't pass a STDERR file handle, maybe that's the issue. You might want to pass an stderr pipe in any case, to read any error messages that Node writes into that stream. – helmbert Jan 12 '16 at 20:47
  • I took it out as an attempt to solve the issue, I'll try adding it back in and will report back. Thank you. – NoToBagels Jan 12 '16 at 20:50
  • I re-added the stderr handle but still no success. It returns nothing. I updated the code above. – NoToBagels Jan 12 '16 at 20:55
  • Too bad. Is there any useful output in either `$template_content` or `$error_content`? What is the value of `$return_value`? – helmbert Jan 12 '16 at 20:56
  • $template content returns "(function(window) { })(this);" which is an empty compiled template. $error_content returns nothing and $return_value returns 0; I've echo'd the $input in the line fwrite($pipes[0], $input); and It displays the uncompiled data, so I know its getting to where it needs to be... – NoToBagels Jan 12 '16 at 21:03
  • @helmbert I figured it out; but thank you for your suggestion. – NoToBagels Jan 12 '16 at 22:09

1 Answers1

2

I have figured out the issue, I was missing the file_put_contents() function when sending data to the pipe...

Here is the working code...

    $template_name = 'template_test.ejs';
    $input = '<img src="/media/<%==category.attrs.image%>" style="width:100%; height:100%;" />';
    $cmd = "node /node_modules/can-compile/bin/can-compile --can 1.1.5 $template_name";

    $descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w")
    );

    $process = proc_open($cmd, $descriptorspec, $pipes);

    if (is_resource($process)) {

    fwrite($pipes[0], file_put_contents($template_name,$input));
    fclose($pipes[0]);

    $template_name = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $return_value = proc_close($process);
    echo $template_name;
}
NoToBagels
  • 152
  • 1
  • 8