I am about to convert a site to use the Slim Framework with the Smarty template engine.
On the current site I have assigned some default smarty vars, but I am not sure how to set them with the Slim framework, so they are set only once.
This is how they are now:
$smarty->assign("fid", $user_profile["id"]);
$smarty->assign("fid_name", $user_profile["name"]);
$smarty->assign("fid_email", $user_profile["email"]);
$smarty->assign('postzip', $users->find_zip_or_post_new($user_profile["id"]));
$smarty->assign('userzip', $users->find_my_zip_code($user_profile["id"]));
$smarty->assign('url', $url);
$smarty->assign('catlist', $adverts->getcategories());
And this is my to-be index.php
/***
* This is the script that will generate the complete site
*/
include_once("includes/classes/class.config.php"); //Configuration file
/*
* Include the Slim framework
*/
require 'libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
use Slim\Slim;
/*
* Include the Smarty template view
*/
require 'libs/Slim/Extras/Views/Smarty.php';
/*
* Set new Slim object
*/
$app = new Slim(array(
'view' => new \Slim\Extras\Views\SmartyView(),
'debug' => true,
'log.enable' => true,
'log.path' => 'logs/',
'log.level' => 4,
'mode' => 'development'
));
//Ad view
$app->get('/', function() use ($app) {
$adverts = new Adverts();
$view = $app->view();
$app->render(
'index.tpl',
array(
'adverts' => $adverts->listadverts()
)
);
});
$app->run();
Should I set them in the SmartyView render function
public function render($template) {
$instance = self::getInstance();
$instance->assign($this->data);
return $instance->fetch($template);
}
Fixed it by using
$app->hook('slim.before.dispatch', function () use ($app) {
});
Related
I am relatively new to Slim so I am not sure if I am making an obvious mistake. I am trying to build the application in a secure way so the get function is not in the index file. The index requires a file that instantiates the slim app and requires the dependencies, settings, and routes files, the route file then requires the homepage which is where the error comes from.
When the code is run the page output is the get function from the homepage is displayed in plain text and then a error message underneath that reads:
"Page Not Found
The page you are looking for could not be found. Check the address bar to ensure your URL is spelled correctly. If all else fails, you can visit our home page at the link below.
Visit the Home Page"
I am sure php is installed properly as when I try the get function in the index page it run fine, I also tested it with phpinfo().
I am using xampp as my development environment.
/**
* Index.php
*/
ini_set('xdebug.trace_output_name', 'football_trivia_game');
ini_set('display_errors', 'On');
ini_set('html_errors', 'On');
ini_set('xdebug.trace_format', 1);
// Include bootstrap
include_once '../includes/bootstrap.php';
/**
* Bootstrap.php
*/
// Start the session
session_start();
// Require vendor
require 'vendor/autoload.php';
// Define app path
$app_path = __DIR__ . "/app/";
// Require settings
$settings = require $app_path . 'settings.php';
// Instantiate container
$container = new \Slim\Container($settings);
// Require the dependencies
require $app_path . 'dependencies.php';
// Instantiate app
$app = new \Slim\App($container);
// Require routes
require $app_path . 'routes.php';
// Execute app
$app->run();
session_regenerate_id(true);
/**
* Setttings.php
*/
// Display errors
ini_set('display_errors', 'On');
ini_set('html_errors', 'On');
// Get app url
$app_url = dirname($_SERVER['SCRIPT_NAME']);
// Get css path
$css_path = $app_url . '/css/app.css';
// Define css path
define('CSS_PATH', $css_path);
// Set settings
$settings = [
"settings" => [
'displayErrorDetails' => true,
'addContentLengthHeader' => false,
'mode' => 'development',
'debug' => true,
'view' => [
'template_path' => __DIR__ . '/templates/',
'twig' => [
'cache' => false,
'auto_reload' => true,
]],
'pdo_settings' => [
'rdbms' => 'mysql',
'host' => 'localhost',
'db_name' => 'fbta_db',
'port' => '3306',
'user_name' => 'username',
'user_password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => true,
]
]
]
];
return $settings;
/**
* Dependencies
*/
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig(
$container['settings']['view']['template_path'],
$container['settings']['view']['twig'],
[
'debug' => true // This line should enable debug mode
]
);
// Instantiate and add Slim specific extension
$basePath = rtrim(str_ireplace('index.php', ''. $container['request']->getUri()->getBasePath()), '/');
$view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));
return $view;
};
/**
* routes.php
*/
require 'routes/homepage.php';
/**
* Homepage Route
*/
// Get Request and Response
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app->get('/', function(Request $request, Response $response) {
$message = 'test';
$response->getBody()->write($message);
return $response;
});
I apologise if I have included too much code, I am just unsure where the problem stems from, any help would be appreciated.
Slim is very flexible. Your must to specify how you are include the route.php script.
My way
index.php:
declare(strict_types=1);
(require __DIR__ . '/../config/bootstrap.php')->run();
bootstrap.php
declare(strict_types=1);
use DI\ContainerBuilder;
use Slim\App;
require_once __DIR__.'/../vendor/autoload.php';
(Dotenv\Dotenv::createImmutable(dirname(__DIR__)))->load();
$containerBuilder = new ContainerBuilder();
// Set up settings
$containerBuilder->addDefinitions(__DIR__.'/container.php');
// Build PHP-DI Container instance
$container = $containerBuilder->build();
// Только для WEB
if ('cli' !== php_sapi_name()) {
// Create App instance
$app = $container->get(App::class);
// Register routes
(require __DIR__.'/routes.php')($app);
// Register middleware
(require __DIR__.'/middleware.php')($app);
} else {
$app = $container;
}
return $app;
In my way routes.php is a script wich MUST return a function:
return function (App $app) {...}
So, in my way, your routes.php returns nothing, because homepage.php returns nothing
So, in my way, your homepage.php muyst be looks like:
return function (App $app) {
$app->get('/', function(Request $request, Response $response) {
$message = 'test';
$response->getBody()->write($message);
return $response;
});
}
So, you must be pass road path from the index.php to route.php in slim. )
Using Slim Framework 2 you could set the template directory using this code:
// Views
$view = $app->view();
$view->setTemplateDirectory('../app/views');
How can I do this using Slim Framework 3?
Currently I'm getting this error:
Fatal error: Call to a member function setTemplateDirectory() on null
Does anybody know how to do this in Slim Framework 3?
You can do it using a \Slim\Container instance:
// Create container
$container = new \Slim\Container;
// Register component on container
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('your/path/to/templates');
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
return $view;
};
Then you can use it:
$app = new \Slim\App($container);
// The route
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
return $this->view->render($response, 'index.html', [
'name' => 'name'
]);
});
$app->run();
Check the official documentation (Mika Tuupola's suggestion).
I have the following index.php:
<?php
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\DI\FactoryDefault;
use Phalcon\Mvc\Url as UrlProvider;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use Phalcon\Mvc\Micro;
try {
// Register an autoloader
$loader = new Loader();
$loader->registerDirs(array(
__DIR__ . '/controllers/',
__DIR__ . '/models/'
))->register();
// Create a DI
$app = new Micro();
$di = new FactoryDefault();
$app->setDI($di);
// Setup the view component
$di->set('view', function () {
$view = new View();
$view->setViewsDir('/views/');
return $view;
});
// Setup a base URI so that all generated URIs include the "legacy" folder
$di->set('url', function () {
$url = new UrlProvider();
$url->setBaseUri('/legacy/api/v1/');
return $url;
});
$di->set('router', function() {
// require __DIR__.'/config/routes.php';
// return $router;
$router = new Phalcon\Mvc\Router(false);
$router->add('/', array(
"controller" => "site",
"action" => "index"
));
$router->notFound(
[
"controller" => "site",
"action" => "ping"
]
);
var_dump($router);
return $router;
});
$app->handle();
} catch (\Exception $e) {
// Do Something I guess, return Server Error message
$app->response->setStatusCode(500, "Server Error");
$app->response->setContent($e->getMessage());
$app->response->send();
}
and the following structure:
--api
----v1
------config
-------- routes.php
------controllers
--------SiteController.php
------models
------views
The problem is that I think my application ignores the router, because I'm getting the following error: if I navigate to "/" - Matched route doesn't have an associated handler. While if I go to some random location like "/12321" it returns Not-Found handler is not callable or is not defined.
Any idea what I'm doing wrong?
Remember that you're setting as base uri /legacy/api/v1/ so all your routes are intended to be appended to that.
$di->set('url', function () {
$url = new UrlProvider();
$url->setBaseUri('/legacy/api/v1/');
return $url;
});
You can't simply access: / but instead, you've to visit /legacy/api/v1/ or if you want to visit /user, you've to visit /legacy/api/v1/user.
Greetings!
I also had some problems with phalcon (1.3.x) routes too. Here's what I did to make them working the way I wanted. Took me a long time to figure that out:
/** #var \Phalcon\Mvc\Router $router */
$router = new Phalcon\Mvc\Router(FALSE); // does not create default routes
$router->removeExtraSlashes(TRUE);
$router->setDefaults(array(
'namespace' => 'Namespace\Controller',
'controller' => 'index',
'action' => 'index'
));
$router->notFound(array(
'controller' => 'index',
'action' => 'show404'
));
Hope it helps.
I have a custom Silex\RouteCollection which I want to register...
class RouteCollectionProvider extends RouteCollection
{
public function __construct() {
$this->add(
'Index',
new Route('/', array(
'method' => 'get',
'controller' => 'index',
'action' => 'index'
)
));
}
}
...during the bootstrapping:
$app = new Silex\Application();
/** here **/
$app->run();
I could use:
$app = new Silex\Application();
$routes = new RouteCollectionProvider();
foreach ($routes->getIterator() as $route) {
$defaults = $route->getDefaults();
$pattern = $route->getPath();
$callback = 'Controller\\'
. ucfirst($defaults['controller'])
. 'Controller::'
. $defaults['action']
. 'Action';
$app->get($pattern, $callback);
}
$app->run();
I don't like having the initialization of those routes right in there.
Do you know any spot in Silex, where this does fit better?
I cannot use $app->register() because it's getting called too late and the routes won't get active in there.
Maybe there is an event I can use with
$app->on('beforeCompileRoutesOrSomething', function() use ($app) {
// initialize routes
}
Or a hook in the Dispatcher?
My aim is to not have a big collection of $app->get() or $app->post() in there. I also know I can ->mount() a controller but then still I have all my get definitions in my bootstrap and not in a Provider.
This post solves the problem: Scaling Silex pt. 2.
$app = new Application;
$app->extend('routes', function (RouteCollection $routes, Application $app) {
$routes->addCollection(new MyCustomRouteCollection);
return $routes;
});
$app->run();
I am trying to setup Slim Framework with the use of Smarty, but something is very wrong.
I can output the template, but it renders the template with the markers and the the data which should replace the markers. In the .tpl I have a marker {#currency#}, but this is also what is printed when I call test.php/test/1
I have this in my test.php
require 'libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
use Slim\Slim;
require 'libs/Slim/Extras/Views/Smarty.php';
$app = new Slim(array('view', new \Slim\Extras\Views\SmartyView()));
$app->get('/test/:id', function($id) use ($app) {
$adverts = new Adverts();
$app->render('viewad.tpl', array(
'viewad' => $adverts->viewsinglead($id),
'imagelist' => $adverts->getadimages($id),
'firstimage' => $adverts->getadimage($id)
));
});
$app->run();
In libs/Slim/Extras/Views/Smarty.php I have set this:
public static $smartyDirectory = '/var/www/vhosts/xxxxx.dk/web/libs/smarty/libs';
public static $smartyCompileDirectory = '/templates_c';
public static $smartyCacheDirectory = '/cache';
public static $smartyTemplatesDirectory = '/templates';
Had an error in the array!
This fixed it:
$app = new Slim(array('view' => new \Slim\Extras\Views\SmartyView()));