I am attempting to convert some PHP code so that it uses Twig for its template engine.
The code I developed previously worked in such a manner that generating a HTML dropdown list involved calling a static method (formTools::generateSchoolList()) which queried a database and then echo the results into the HTML (spaghetti code).
I've been having some issues creating and then displaying the result of functions and I'm hoping someone can help me troubleshoot the errors I am receiving. In formTools.class.php, I am referring to a single static method for this example and although the Twig Docs suggested using an anonymous method (I called the static function above within the anonymous function), I wasn't able to get that to work, so I made the Twig_SimpleFunction callable parameter the static method directly.
If I do that I get (using return within the static method):
Parse error: syntax error, unexpected '<' in /Path_To_Vendor/vendor/twig/twig/lib/Twig/Environment.php(332) : eval()'d code on line 46
Fatal error: Class '__TwigTemplate_96fa0bd50202e1016defd78dc63d0ee7f8c3432728ffb0946f67a6a1e5c89437' not found in /Path_To_Vendor/vendor/twig/twig/lib/Twig/Environment.php on line 346
If I echo within static function, I get:
Fatal error: Call to undefined method Twig_SimpleFunction::compile() in /path_to_vendor/vendor/twig/twig/lib/Twig/Node/Expression/Call.php on line 27
formTools.class.php
/**
* Generates a list of all available schools in a dropdown box
*
* #throws Exception
*/
static function generateSchoolList() {
$db = new database(databaseHost, databaseUser, databasePass, databaseName);
$query = "SELECT * FROM `schoolCodes`";
$codes = $db->query($query);
if (isset($codes)) {
$result = "<select name='schoolCode'>";
$result .= "<option class='dropdown' value=''> </option>";
$result .= "<option class='dropdown' disabled>----</option>";
foreach ($codes as $code) {
$result .= "<option class='dropdown' value='{$code['codeID']}'>{$code['schoolName']} ({$code['code']})</option>";
}
$result .= "</select>";
**echo/return** $result;
} else {
throw new Exception("The schoolCodes table is empty.");
}
}
formviewer.php
require_once('../vendor/autoload.php');
$ft = new formTools();
$it = new ingestTasks();
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('../templates');
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('generateSchoolList',
formTools::generateSchoolList()
);
$twig->addFunction($function);
$template = $twig->loadTemplate('viewPlayersByRoster.twig');
echo $twig->render($template);
viewPlayersByRoster.twig
{% extends "base.twig" %}
{% block title %}View Players by Roster{% endblock %}
{% block content %}
<p class="formDesc">This form is for viewing all players on a given roster.</p>
<form action="formviewer.php?action=viewPlayersByRoster" target="_self" method="post">
<input hidden="hidden" value="viewPlayersByRoster" name="action" title="action"/>
<table>
<tr>
<td class="rightAlignText"><label for="schoolCode">School:</label></td>
<td>{{ generateSchoolList() }}</td>
</tr>
</table>
</form>
{% endblock %}
EDIT:
Using PHP 5.5.24 (cannot update past this), Twig 1.18.2 and using Composer.
composer.json
"require": {
"twig/twig": "v1.18.2"
},
"autoload": {
"classmap": ["libs/"]
}
EDIT 2:
Changed to what tacone said and got this:
Catchable fatal error: Object of class __TwigTemplate_96fa0bd50202e1016defd78dc63d0ee7f8c3432728ffb0946f67a6a1e5c89437 could not be converted to string in /path_to_vendor/vendor/twig/twig/lib/Twig/Loader/Filesystem.php on line 216
/Filesystem.php
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
}
formTools.class.php
public function __toString() {
return $this->formTools;
}
You are executing the static method instead of passing its coordinates.
Try using PHP classical callback syntax:
$function = new Twig_SimpleFunction('generateSchoolList', ['formTools', 'generateSchoolList']);
$twig->addFunction($function);
See also https://stackoverflow.com/a/29629460/358813
Related
I'm working on writing a Bolt extension to parse an XML file and return the deserialised object tree for the XML. The parsing and deserialising is working like a charm but I cannot get the filename from the page record working as a parameter for the Twig function.
Extension code (simplified) is:
class CompetitionExtension extends SimpleExtension
{
protected function registerTwigFunctions()
{
return [
'competition' => 'competitionFunction',
];
}
/**
* Load and parse the competition XML.
*
* #param string $filename
* #return Competition
*/
public function competitionFunction(string $filename) : Competition
{
$competition = null;
$loader = new FileLoader($filename);
if ($loader->openFile()) {
$competition = $loader->parse();
}
return $competition;
}
}
The contenttype (extended the homepage) addition is:
competitionxml:
type: file
upload: competitions
group: content
Upload of the file is also no problem but the following Twig template code gives an error:
{% set xmlfile = homepage.competitionxml %}
{% set comp = competition(xmlfile) %}
Using dump I see that xmlfile has the correct value. But I get the following error:
An exception has been thrown during the rendering of a template ("Notice: Undefined variable: filename") in "index.twig" at line 27.
So how can I use the filename of the attachment as parameter for the Twig function?
I have an error in symfony2 unit testing , symfony : 2.7.1
when I use siblings() I have a the error:
InvalidArgumentException: The current node list is empty.
the twig file:
<h1>ddd</h1>
<p>ahmedghgh</p>
<ul>
<li>dddd</li>
<li>eeee</li>
<li>ffff</li>
</ul>
</p>bye</p>
<form action ="" method="GET" name ="nameForm">
<input type="text" value ="name" name="name">
<input type="submit" value ="send" name="send">
</form>
BasicControllerTest.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace TestingSymfony\BasicBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class BasicControllerTest extends WebTestCase {
public function testHelloContent() {
$client = static::createClient();
$crawler = $client->request('GET', '/helloworld');
$h1 = $crawler->filter('h1')->eq(0);
$p1 = $crawler->filter('p')->first();
$ul = $p1->siblings()->eq(0);
$l1 = $ul->children()->first();
$l2 = $ul->children()->eq(1);
$l3 = $ul->children()->last();
$p2 = $crawler->filterXPath("//p")->last();
}
}
Once I remove the siblings , all is ok and no error appeared
You have a typo in the twig files: check that the P tag is open and closed correclty, as follow:
<p>bye</p>
instead of
</p>bye</p>
Hope this help
Your filterdid not return any results as you had a typo. That is why it crashed. However, for others who did not have any typo, that's how I solved this issue, by adding a try catch.
try {
$p1 = $crawler->filter('p')->first();
} catch (\InvalidArgumentException $e) {
// Handle the current node list is empty..
}
I am trying to write a plugin for elgg that's similar to the bookmarks plugin. I found out php doesn't do "innerHTML," so I added some code to my plugin's library to accomplish that. But I am getting this error:
PHP Fatal error: Call to undefined function DOMinnerHTML() in
/var/www/html/mod/mypluginname/actions/mypluginname/save_address.php
on line 71, referer:
http://www.example.com/mypluginname/add_address/49
The calling code:
mytitle = $doc->getElementById('myTitle');
if($mytitle){
$title = DOMinnerHTML($mytitle);
}
Line 71 of /var/www/html/mod/mypluginname/actions/mypluginname/save_address.php is:
$title=DOMinnerHTML($mytitle);
The function is in /var/www/html/mod/mypluginname/lib/mypluginname.php:
function DOMinnerHTML(DOMNode $element)
{
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$innerHTML .= $element->ownerDocument->saveHTML($child);
}
return $innerHTML;
}
Any idea why this function isn't considered "defined?"
The bookmarks plugin is using the library loading function elgg_load_library. This allows you to reference a library by name instead of absolute path, which makes things slightly more flexible.
If you want to use that in your plugin, you'll need to use elgg_register_library in start.php.
You have to include or require mypluginname.php ?
I have been writing procedural php for years and am very comfortable with it. Recently I decided to rework an existing site and switch to PDO and OOP. Everyone is telling me that this is a better way to go but the learning curve is killing me. When trying to call a class, I get the following.
Menu Builder
vbls: 5 1
Notice: Undefined variable: Menu in /home/lance/DallyPost/projectWebSite/trunk/1/core/modules/menuBuilder.php on line 9
Fatal error: Call to a member function menuFramework() on a non-object in /home/lance/DallyPost/projectWebSite/trunk/1/core/modules/menuBuilder.php on line 9
The procedure is that I have included menu.php at the top of index.php, prior to including the following script:
<?php
//menuBuilder.php
echo"<h2>$pageTitle</h2>";
$pub = $_URI_KEY['PUB'];
$dir = $_URI_KEY['DIRECTORY'];
echo"vbls: $pub $dir";
if($Menu->menuFramework("$pub", "$dir") === false) {
echo"The base menu framework failed to build correctly.";
}
else{
echo"<p>The base menu framework has been successfully constructed.</p>";
}
?>
As you can see, the above script calls a method in the Menu class:
<?php
//menu.php
class Menu{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function menuFramework($pub, $directory){
$link = "/" . $directory . "/index.php/" . $pub . "/home/0/Home-Page/";
$inc = "core/menus/" . $pub . "category.php";
$file = "core/menus/" . $pub . "menuFramework.php";
$text = "<nav class=\"top-bar\" data-topbar>";
$text .= "<ul class=\"title-area\">";
$text .= "<li class=\"name\">";
$text .= "<h1>Home Page</h1>";
$text .= "</li>";
$text .= "</ul>";
$text .= "include($inc)";
$text .= "</nav>";
//write text to a file
if(file_put_contents($file, $text)){
return true;
}
else{
return false;
}
}
... rest of file not shown
Can you help me understand why I am getting this error. My understanding is that the variable was or should have been defined when I included menu.php, which was done before which was called a the top if index.php
Thanks
add this at the top of the script
$menu = new Menu($dbHandle);
That's not how classes work. You can't reference an entire class, Menu, with a variable, $Menu, to invoke instance methods.
You need to create an instance of your class on which to invoke methods:
$menu = new Menu(...);
You can create class-level "static" methods which are invoked on the class itself, but that syntax doesn't involve $Menu. You would use Menu::method_name() for that.
You are calling $Menu->
so your are a calling a variable called Menu, instead of the class Menu.
anyways, that function is not static, so you need to instantiate an object.
For that, add a this line:
$menu = new Menu($db);
where $db is your database object, if you really need it, or null if you dont (i cannot say with that code fragment)
and then call
$menu->menuFramework(...)
I'm coding an app in PHP for school work and I'm using Twig template engine lonely (without a framework).
I got a file which initialize Twig in my project and I use it in all files that need it.
include_once('./Twig/lib/Twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('./templates');
$twig = new Twig_Environment($loader, array(
'cache' => false,
'charset' => 'utf-8'
));
I have a Twig Function which returns the path to my static files folder. But when I run addFunction($my_function) I got the error below :
Warning: Missing argument 1 for {closure}()
My Twig function:
$url_for_static = new Twig_SimpleFunction('static_folder', function () {
$static_folder = "./static" ;
return $static_folder ;
});
$twig->addFunction($url_for_static);
I know this answer is really late but i finally found a solution to my problem. My Twig function declaration was wrong.
This worked for me :
`
function blank_space($size=100) {
echo "<div class='grid-". $size ." hidden'> <span> hidden </span> </div>" ;
}
$twig->addFunction('blank_space', new Twig_Function_Function('blank_space')) ;
`
I have never used Twig before, but it seems the closure is called with an argument but you didn't define any arguments in your closure. Try this:
$url_for_static = new Twig_SimpleFunction('static_folder', function ($arg) {
var_dump($arg);
$static_folder = "./static" ;
return $static_folder ;
});
I know this answer is really late but i finally found a solution to my problem. My Twig function declaration was wrong.
This worked for me :
function blank_space($size=100) {
echo "<div class='grid-". $size ." hidden'> <span> hidden </span> </div>" ;
}
$twig->addFunction('blank_space', new Twig_Function_Function('blank_space')) ;