twig error when using in slim - twig

Hi I need interate twig to Slim application, I install twig with composer and im my script I have
<?php
use Slim\Slim;
use Slim\Views\Twig;
use Noodlehaus\Config;
use Codecourse\User\User;
session_cache_limiter(false);
session_start();
ini_set('display_errors','On');
define('INC_ROOT', dirname(__DIR__));
require INC_ROOT.'/vendor/autoload.php';
$app = new Slim([
'mode' => file_get_contents(INC_ROOT.'/mode.php'),
'view' => new Twig(),
'template.path' => INC_ROOT . '/app/views'
]);
$app->view->setTemplatesDirectory("/views");
$app->configureMode($app->config('mode'), function() use ($app) {
$app->config = Config::load(INC_ROOT . "/app/config/{$app->mode}.php");
});
echo $app->config->get('db.driver');
require 'database.php';
$app->container->set('user', function() {
return new User;
});
$app->get('/', function() use ($app) {
$app->render('home.php');
});
when I run script I obtain this error:
Type: Twig_Error_Loader
Message: The "/views" directory does not exist.
File:
C:\xampp\htdocs\authentication\vendor\twig\twig\lib\Twig\Loader\Filesystem.php

The Slim documentation for configuring the template path might be a little misleading; you only need to set template.path or call View::setTemplatesDirectory but not both.
If you wanted to use the latter, then it would simply be :
$app->view->setTemplatesDirectory(INC_ROOT . '/app/views');

My stupid mistake
i must use
'templates.path' => INC_ROOT . '/app/views'
and I have
'template.path' => INC_ROOT . '/app/views'

Related

How to enable and disable perf_hook based on Flag

We have large code with lot of function called in series . For performance improvement we want to measure the time between to specific point.
Step by step we want to make improvement. I was thinking of making user of perf_hook
Our best use case will be using as below , as per the lib
const { PerformanceObserver, performance } = require('perf_hooks');
const obs = new PerformanceObserver((items) => {
console.log(items.getEntries()[0].duration);
performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');
performance.mark('A');
doSomeLongRunningProcess(() => {
performance.measure('A to Now', 'A');
performance.mark('B');
performance.measure('A to B', 'A', 'B');
});
I looked and searched in lib as well as web , did not find any env variable to enable or disable the perf_hook, so enable and disable the code in PROD stage.
playing around the code .
Just putting the declaration based on condition
let obs = null;
//ACTIVATE or DEACTIVATE
if( true || false) {
obs = new PerformanceObserver((items) => {
console.log(items.getEntries()[0].duration);
performance.clearMarks();
});
obs.observe({ type: 'measure' });
}

How to add common model to Twig and Slim4

I'm using Twig and Slim4 with DI container (the same as this tutorial: https://odan.github.io/2019/11/05/slim4-tutorial.html).
I would like to know how can I add a common model to all my twig views, for example user object, general options and something like this.
This is the container Twig initialization:
TwigMiddleware::class => function (ContainerInterface $container) {
return TwigMiddleware::createFromContainer($container->get(App::class), Twig::class);
},
// Twig templates
Twig::class => function (ContainerInterface $container) {
$config = $container->get(Configuration::class);
$twigSettings = $config->getArray('twig');
$twig = Twig::create($twigSettings['path'], $twigSettings['settings']);
return $twig;
},
The twig middleware is the Slim standard one: Slim\Views\TwigMiddleware
You can add global variables to Twig environment, so they are accessible in all template files:
(To be able to provide a sample code, I assumed you have defined a service like user-authentication-service which is capable of resolving current user)
// Twig templates
Twig::class => function (ContainerInterface $container) {
//...
$twig = Twig::create($twigSettings['path'], $twigSettings['settings']);
$twig->getEnvironment()->addGlobal(
'general_settings',
[
'site_name' => 'my personal website',
'contact_info' => 'me#example.com'
]);
$twig->getEnvironment()->addGlobal(
'current_user',
// assuming this returns current user
$container->get('user-authentication-service')->getCurrentUser()
);
return $twig;
},
Now you have access to general_settings and current_user in all of your template files.

Orchard CMS Contrib.Review module

I am beginner in Orchard CMS and i need add voting functionality to content. I have installed Contib.Vote and Contrib.Review modules. After that i have added Review part to page content type. Also, i have executed recipe. At the first look everything is fine, but link for review refer to the same page with # symbol and nothing is happenning by clicking on it. It seems like module does not work or work incorrectly. Please help with my problem.
UPD.
Hi devqon and thanx for your help. Your answer was really useful for me. According to your advice i was looking around javascript inside Review Part view file (Parts_Reviews.cshtml). Just for a test i changed its source code a little bit.
#using (Script.Foot())
{
<script type="text/javascript">
//<![CDATA[
(function () {
var numberOfReviewsToShowByDefault = 5;
var $showAllReviewsLink = $('#showAllReviewsLink');
var $deleteReviewConfirmationDialogDiv = $('#deleteReviewConfirmationDialogDiv');
$deleteReviewConfirmationDialogDiv.dialog({ autoOpen: false, modal: true, resizable: false });
$('#deleteReviewLink').click(function () {
$('#reviewId').val($(this).attr("data-review-id"));
ShowDeleteReviewDialog();
return false;
});
$('#showReviewFormLink').click(function () {
$('#createReviewLinkDiv').slideToggle('fast', function () { $('#reviewFormDiv').slideToggle('fast'); });
return false;
});
$('#cancelCreateReviewLink').click(function () {
$('#reviewFormDiv').slideToggle('fast', function() { $('#createReviewLinkDiv').slideToggle('fast'); });
return false;
});
$('#deleteReviewForm').submit(function () {
$('input[type=submit]', this).attr('disabled', 'disabled');
});
$('#cancelDeleteReviewButton').click(function () {
CloseConfirmationDialogDiv();
return false;
});
var rowCount = $('#reviewsList li').length;
if (rowCount > numberOfReviewsToShowByDefault) {
SetupToggle();
}
if (document.location.hash === '#Reviews') {
var topPx = $('#reviews-heading').position().top;
$('body,html').animate({ scrollTop: topPx }, 'slow');
}
if ($("#comment").length) {
var characterCountUpdater = new CharacterCountUpdater($("#comment"), $("#commentCharactersLeft"));
setInterval(function() { characterCountUpdater.UpdateCharacterCount(); }, 100);
$("#comment").keypress(function() { characterCountUpdater.UpdateCharacterCount(); });
if ($("#comment").val().length) {
$("#showReviewFormLink").trigger("click");
}
}
function CharacterCountUpdater(commentBox, charactersLeftBox)
{
this.commentBox = commentBox;
this.charactersLeftBox = charactersLeftBox;
this.maxLength = commentBox.attr("maxlength");
commentBox.removeAttr("maxlength");
return this;
}
Now form for review is displayed. The form looks good, submit button works, character counter works too. But i still can't apply my rating. Stars not react on clicking. That is why submit operation ends with error 'In order to submit a review, you must also submit a rating.'. Look like something inside Parts.Stars.NoAverage.cshtml does not work. Please, help me.
According to the project's site it is a known issue: broken from version 1.7.2.
When looking at the code of the Parts_Reviews.cshtml it says the following on lines 20-24:
string showReviewUri = "#";
if (!Request.IsAuthenticated)
{
showReviewUri = Url.Action("LogOn", "Account", new { area = "Orchard.Users", ReturnUrl = Context.Request.RawUrl });
}
and on line 29:
<div id="createReviewLinkDiv"><span id="createReviewLinkSpan">#noReviewsYetText<a id="showReviewFormLink" href="#showReviewUri">#reviewLinkText</a></span></div>
Therefore, it was intended to let the anchor be # when the request is authenticated (you are logged on). This means it probably will be handled in JavaScript, which can be seen on lines 105-112:
$('#showReviewFormLink').click(function () {
$('#createReviewLinkDiv').slideToggle('fast', function () { $('#reviewFormDiv').slideToggle('fast'); });
return false;
});
$('#cancelCreateReviewLink').click(function () {
$('#reviewFormDiv').slideToggle('fast', function() { $('#createReviewLinkDiv').slideToggle('fast'); });
return false;
});
This piece of code should let you see the form to write a review, so something is going wrong there presumably. When there's something wrong in this jQuery code it probably gives an error in the console, so check out the browser's console when you click the 'Be the first to write a review' link.
This should get you further, if you don't know what to do please provide the error and I will try to dig more. I haven't downloaded the module so I don't have live feed.
Console of Firefox tells: $(...).live is not a function. It refers to Contrib.Stars.js source code file. This function is not supported in jquery now and i replaced it by .on() function in all places api.jquery.com/on. Now module works fine.
Check out my comment at the site below to see how I was was able to get it working again on Orchard 1.8.1:
Orchard Reviews Project Site
You basically just need to change 3 different lines in the Contrib.Stars.js file but I would recommend copying the .js file along with the Review module's different views to a custom theme directory, in order to override everything and force the Reviews module to use your edited .js file:
On line 12 & 13:
Change this:
$(".stars-clear").live(
"click",
To this:
$("body").on(
"click", ".stars-clear",
On line 44 & 45:
Change this:
.live(
"mouseenter",
To this:
.mouseenter(
On line 48 & 49:
Change this:
.live(
"mouseleave",
To this:
.mouseleave(

Twig is not loading in Silex

I'm trying to run application with Silex FW. I have similar source code as in example:
require_once __DIR__.'/silex.phar';
$app = new Silex\Application();
$app['debug'] = true;
$app->register(new Silex\Provider\TwigServiceProvider(), array(
'twig.path' => __DIR__ . '/views',
'twig.class_path' => __DIR__ . '/vendor/twig/lib',
));
$app->get('/hello/{name}', function ($name) use ($app) {
return $app['twig']->render('hello.twig', array(
'name' => $name,
));
});
$app->run();
But I'm getting this error:
Fatal error: Class 'Twig_Environment' not found in phar:///var/www/silex/silex.phar/src/Silex/Provider/TwigServiceProvider.php on line 40
Stack trace:
1. {main}() /var/www/silex/index.php:0
2. Silex\\Application->run() /var/www/silex/index.php:20
3. Silex\\Application->handle() phar:///var/www/silex/silex.phar/src/Silex/Application.php:396
4. Symfony\\Component\\HttpKernel\\HttpKernel->handle() phar:///var/www/silex/silex.phar/src/Silex/Application.php:411
5. Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw() phar:///var/www/silex/silex.phar/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:72
6. call_user_func_array() phar:///var/www/silex/silex.phar/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:128
7. {closure}() phar:///var/www/silex/silex.phar/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:128
8. Pimple->offsetGet() phar:///var/www/silex/silex.phar/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php:15
9. {closure}() phar:///var/www/silex/silex.phar/vendor/pimple/pimple/lib/Pimple.php:81
10. Silex\\Provider\\{closure}() phar:///var/www/silex/silex.phar/vendor/pimple/pimple/lib/Pimple.php:120
This problem was also posted on GitHub.
Solution is to use Composer and autoload.php.
With that approach, your twig.class_path probably needs to be vendor/twig/twig/lib (extra twig directory) ...
But twig.class_path is actually unnecessary, with composer, which is the better approach (as kuboslav notes).

Drupal 6 File Handling

I am handling file upload field in a form using Drupal 6 form APIs. The file field is marked as required.
I am doing all the right steps in order to save and rename files in proper locations.
upload form
$form = array();
....
$form['image'] = array(
'#type' => 'file',
'#title' => t('Upload photo'),
'#size' => 30,
'#required' => TRUE,
);
$form['#attributes'] = array('enctype' => "multipart/form-data");
...
form validate handler
$image_field = 'image';
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$image_field])) {
$file = file_save_upload($image_field);
if (!$file) {
form_set_error($image_field, t('Error uploading file'));
return;
}
$files_dir = file_directory_path();
$contest_dir = 'contest';
if(!file_exists($files_dir . '/' . $contest_dir) || !is_dir($files_dir . '/' . $contest_dir))
mkdir($files_dir . '/' . $contest_dir);
//HOW TO PASS $file OBJECT TO SUBMIT HANDLER
$form_state['values'][$image_field] = $file;
file_move($form_state['values'][$image_field], $files_dir."/" . $contest_dir . "/contest-". $values['email']. "-" . $file->filename);
}
else {
form_set_error($image_field, 'Error uploading file.');
return;
}
On submiting form
Form always reports an error Upload photo field is required. although files are getting uploaded. How to deal with this issue?
How to pass file information to submit handler?
your handler is wrong. You never should touch $_FILES or $_POST variables in drupal, instead you should only use the drupal tools. Said that, the implementation you should is like that:
function my_form_handler(&$form,&$form_state){/** VALIDATION FILE * */
$extensions = 'jpeg jpg gif tiff';
$size_limit = file_upload_max_size();
$validators = array(
'my_file_validate_extensions' => array($extensions),
'my_file_validate_size' => array($size_limit),
);
$dest = file_directory_path();
if ($file = file_save_upload('image', $validators, $dest)) {
//at this point your file is uploaded, moved in the files folder and saved in the DB table files
}
}
I think you'll want to use the filefield module and append it to a form, as described in:
Drupal Imagfield/Filefield in custom form
The question has a link to the solution:
http://sysadminsjourney.com/content/2010/01/26/display-cck-filefield-or-imagefield-upload-widget-your-own-custom-form
From the Drupal 6 Form API docs:
"Note: the #required property is not supported (setting it to true will always cause a validation error). Instead, you may want to use your own validation function to do checks on the $_FILES array with #required set to false. You will also have to add your own required asterisk if you would like one."
Old post, but I'm looking for something similar and figured I add that.

Resources