I want to import an HTML file from inside a Twig template. The HTML file is located at /var/files/5 (with no extension). And I render the template like this:
$path = $_SERVER['DOCUMENT_ROOT'] . '/../var/files/5';
$content = $this->get('templating')->render('ProConvocationBundle:Default:definitive-view.html.twig', array('path' => $path));
Inside the Twig template I import the HTML file like this:
{% include path %}
but it is not finding the path: Unable to find template "/myDocumentRoot/../app/var/files/5"
I've also tried several relative paths without success. Any idea of how to achieve it?
What causes this exception?
After digging in the Twig code a little, the following seems to cause this exception:
Twig tries to load the file from a known path/namespace, being bundle names (like /var/www/myApplication/src/AcmeBundle/Resources/views) and the app path being myApplication/app/Resources/views). Anyway it doesn't accept absolute paths, since it always tries to add a known path to the beginning of the given file.
<?php
// Twig/Loader/Filesystem.php
class Twig_Loader_Filesystem {
// ...
protected function findTemplate()
{
// ...
foreach ($this->paths[$namespace] as $path) {
if (is_file($path.'/'.$shortname)) {
return $this->cache[$name] = $path.'/'.$shortname;
}
}
throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
}
So it basically isn't possible to include a file by an absolue path, like in your example.
How to solve this?
You've got a bunch of possibilities to achieve this behaviour:
Add the path to the template loader
See post by #Adam Elsodaney
Move the file
You could simply move your file from app/var/files to app/Resources/views/var/files and use the path var/files/5 to include the file. This is probably not a suitable solution, since you want to keep those files in place.
Write a Twig Extension
You could write your own extension that provides a function named something like include_absolute() that simply returns file_get_contents($yourPath).
More on Twig extensions: http://symfony.com/doc/current/cookbook/templating/twig_extension.html
Be aware that you would might need to add the |raw filter to the output of the Twig function since a lot of stuff gets escaped everywhere.
In Symfony, you should make everything relative to the Kernel root directory which is the app directory.
$uploadedTemplatesDir = $this->get('kernel')->getRootDir() . '/../var/files';
Then add this to your templating loader
$this->get('twig.loader')->addPath($uploadedTemplatesDir);
Related
I wrote custom classes and want to use them in pimcore application.
I took them to /website/lib/Custom directory on server. Afterwards, I wrote recursive script includer for each Class located in the directory and included that script in /index.php file.
It is absolutely not pimcore standard but it works.
In pimcore/config/startup.php exists snippet:
$autoloaderClassMapFiles = [
PIMCORE_CONFIGURATION_DIRECTORY . "/autoload-classmap.php",
PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY . "/autoload-classmap.php",
PIMCORE_PATH . "/config/autoload-classmap.php",
];
$test = PIMCORE_ASSET_DIRECTORY;
foreach ($autoloaderClassMapFiles as $autoloaderClassMapFile) {
if (file_exists($autoloaderClassMapFile)) {
$classMapAutoLoader = new \Pimcore\Loader\ClassMapAutoloader([$autoloaderClassMapFile]);
$classMapAutoLoader->register();
break;
}
}
I guess that this provides inclusion of all those classes put into returning array from autoload-classmap.php.
Having in mind that /pimcore/config/autoload-classmap.php exists, the mentioned loop would break at first iteration so classes that I would put into custom autoload-classmap are not going to be included in project.
My question is can I change files from /pimcore directory and expect that everything would be fine after system update?
No, you should not overwrite anything in the pimcore directory, since the files in there get overwritten by the update mechanism.
You can do what you want by using the /website/config/startup.php which will not get overwritten:
https://www.pimcore.org/wiki/display/PIMCORE4/Hook+into+the+startup-process
But instead of loading all your classes as you did, take advantage of the autoloader by adding this to the /website/config/startup.php:
// The first line is not absolutely necessary, since the $autoloader variable already gets
// set in the /pimcore/config/startup.php, but it is a more future-proof option
$autoloader = \Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('Custom');
If you are properly using namespaces and naming your files correctly that's all you need to do.
I have a primary controller located in secure/application/modules/gps/controllers that has a constructor that looks like this:
public function __construct()
{
parent::__construct();
$this->load->model('gps_model');
Assets::add_module_js('gps', 'gps.js');
Assets::add_module_css('gps','gps.css');
if($this->input->get('clear') != false){
$this->session->sess_destroy();
}
}
My CSS file that I am trying to include is located in the folder secure/application/modules/gps/assets/css. The code executes fine without warning, but the CSS file does not get included for any methods. Is there a configuration setting the may override the assets directory, or is there some other reason it's not being found/added? (The JS file is not being added either. The bonfire base CSS files (screen.css) IS getting loaded fine.
We found the solution to our particular problem.
The assets/cache directory did not exist. Once the server could write (it must exist and be writeable!) to the [document_root]/bonfire/public/assets/cache directory all was good.
This is not a solution, but I have faced the same problem and found help with the below information.
It'll added in your page but can you just look on ctrl+u source where bonfire will auto rename your file.
For example : In my code I have added id_proof_master.css file like below.
public function __construct()
{
parent::__construct();
$this->auth->restrict($this->permissionView);
$this->load->model('id_proof_master/id_proof_master_model');
$this->lang->load('id_proof_master');
$this->form_validation->set_error_delimiters("<span class='error'>", "</span>");
Template::set_block('sub_nav', 'master/_sub_nav');
Assets::add_module_js('id_proof_master', 'id_proof_master.js');
Assets::add_module_css('id_proof_master', 'id_proof_master.css');
}
And it's working fine but when I have check in source view (ctrl+u) it will show file name like "id_proof_master_master_mod.min.css" so can you just check it out in source; maybe it'll show you with some other name like my file.
Following the documentation written here, I added a file to lib directory containing:
<?php
namespace Theme\URIs;
/**
* Returns theme images directory uri
*/
function get_images_directory_uri() {
return get_template_directory_uri() . '/assets/images';
}
Which I then tried calling from a template file with:
<?php print Theme\URIs\get_images_directory_uri(); ?>
Calling this however, returned a Fatal error: Call to undefined function Theme\URIs\get_images_directory_uri().
The solution is to add the file to the $sage_includes array in functions.php, so it looks like this:
$sage_includes = [
'lib/assets.php', // Scripts and stylesheets
'lib/extras.php', // Custom functions
'lib/setup.php', // Theme setup
'lib/titles.php', // Page titles
'lib/wrapper.php', // Theme wrapper class
'lib/uris.php' // Project URIs
];
This imports the file to be used in the theme.
The present documentation does not explain this. (I assumed it simply imported all files in the libs directory...)
Not the question (I can't comment yet) but unless you've changed the directory structure your function should probably return:
get_template_directory_uri() . '/dist/images';
As the images in /assets/images get optimised and then copied to /dist/images.
I am just wondering, I actually decided to go down a different route.
I create this file A
C:\somefolder\templates\mytemplate\joomlaoverwrites\libraries\joomla\document\html\renderer\head.php
which overwrites a joomla library file:
C:\somefolder\libraries\joomla\document\html\renderer\head.php
I use the overwrite by using
require_once(__DIR__ . '/joomlaoverwrites/libraries/joomla/document/html/renderer/head.php');
in my index.php of my template
This actually works.
What I now want to do is use my file just as a wrapper class, and sneak my changes into it before returning the answer. E.g.:
public function fetchHead($document)
{
$joomlasOriginalHead = callOriginalFunctionFetchHeadFromTheJoomlaImplementation();
//do my changes to joomlas original answer and return that
}
E.g. from that overwrite, I want to call the original file. Is that somehow possible?
I am using Code Igniter, The HMVC library, and Smarty with this library.
Smarty is working fine by default, however if I try to use smarty's inheritance feature ( {extends file="master.tpl"}) then we run into an issue.
The extends feature does not look in the module views folder for the extended file (in the above's case master.tpl), instead it only looks in the application/views/ folder and throws an error if it cannot find it.
I could add APPPATH."modules/smartytest/views" to the $config['template_directory'] array in the smarty config file. but that throws an error for each item in the array it checks first for the file. filemtime(): stat failed for application/views/master.tpl
and that has the added issue of, if I have three modules all the the array and the modules all have a master.tpl then no matter what module I call the extend from it will load the first one found.
So, is there a way to get smarty's extend function to behave nicely with the HMVC modules?
Ah, found a working solution,
in My_Parser.php edit the block at line 30 so it reads:
// Modular Separation / Modular Extensions has been detected
if (method_exists( $this->CI->router, 'fetch_module' ))
{
$this->_module = $this->CI->router->fetch_module();
//add the current module view folder as a template directory
if ($this->_module !== '')
$this->CI->smarty->addTemplateDir(APPPATH."modules/".$this->_module.'/views');
}
The one drawback of this method is that smarty will look in your application/views folder before the module views folder. if someone knows a solution to that then it would be fantastic.
The problem is that CI is not checking error_reporting() returns 0, because Smarty is using the # control operator:
So add the line at the top of the function "_exception_handler":
if (error_reporting() == 0) return;
To the "Common.php" file in the "_exception_handler" function (line 469), or create your own function with the same name before calling "CodeIgniter.php" in the index.php file.
Best!