I'm trying to do a simple background image on a page in my SlimPHP web app.
In my CSS file (which is loaded fine) I have:
.image1 {
background-color: transparent;
background: url("image1.jpg");
}
and my structure is:
-- project
-- app
-- routes
-- templates
-- www
-- css
-- stylesheet.css
-- image1.jpg
-- js
-- i
-- image1.jpg
In the network tab I get 403 Forbidden because slim is trying to access it as a page.
I have tried a few variations such as background-image, "../i/image1.jpg", but always get the same issues.
I can't find any other questions anywhere like this so there must be something simple I am missing!
I know SlimPHP fairly well but do not have much experience in CSS so any help would be appreciated!
Thanks
Additional:
Example of page request:
$app = new \Slim\Slim(array(
'templates.path' => '../templates',
));
$app->container->singleton('log', function () {
$log = new \Monolog\Logger('slim-skeleton');
$log->pushHandler(new \Monolog\Handler\StreamHandler('../logs/app.log', \Monolog\Logger::DEBUG));
return $log;
});
$app->view(new \Slim\Views\Twig());
$app->view->parserOptions = array(
'charset' => 'utf-8',
'cache' => realpath('../templates/cache'),
'auto_reload' => true,
'strict_variables' => false,
'autoescape' => true
);
$app->view->parserExtensions = array(new \Slim\Views\TwigExtension());
// Twig
$loader = new Twig_Loader_Filesystem(dirname(dirname(__FILE__)) . '/templates');
$twig = new Twig_Environment($loader);
/**
* Default home page
*/
$app->get('/', function() use ($app) {
$app->redirect('/home');
});
/**
* Index page
*/
$app->get('/home', function() use ($app, $twig) {
$params['page_title'] = 'home';
$template = $twig->loadTemplate('routes/index.html.twig');
$template->display($params);
});
Related
I'm using the plugin cakephp-glide in my Cakephp4 App.
I want to delete Glide cache of an image just after the image is deleted.
My plugin FileManager triggers an event 'afterDelete' when the image file is deleted :
// in FileManager.FichiersTable
public function afterDelete(Event $event, EntityInterface $entity, ArrayObject $options)
{
$fichier = new File(WWW_ROOT . $entity->url);
$fichier->delete();
$afterDeleteEvent = new Event('FileManager.Fichiers.afterDelete', $this, [
'file' => $entity
]);
$this->getEventManager()->dispatch($afterDeleteEvent);
}
and I want to catch the event in bootstrap of my application to delete the cache of the image :
//in bootstrap.php
EventManager::instance()
->on(
'FileManager.Fichiers.afterDelete',
function (Event $event) {
// Delete cache of $event->getData('file')
$filename = $event->getData('file')->filename;
$server->deleteCache($filename); // How to get the instance $server ???
}
);
But I don't know how to get the Glide Server instance ?
I can't find a method in the plugin to get it.
If someone could help me...
On ADmad advices, the solution is to store the Glide server config in Configure and then use this config both in routes for the ADmad/Glide plugin configuration and in my event listener to create a new server instance.
//in bootstrap.php
//'ADmad/Glide.server' will be used in routes to configure the plugin and in my event listener below to create a new server instance.
Configure::write('ADmad/Glide.server', [
// Path or League\Flysystem adapter instance to read images from.
// http://glide.thephpleague.com/1.0/config/source-and-cache/
'source' => WWW_ROOT,
// Path or League\Flysystem adapter instance to write cached images to.
'cache' => WWW_ROOT . 'files' . DS . 'cache',
// URL part to be omitted from source path. Defaults to "/images/"
// http://glide.thephpleague.com/1.0/config/source-and-cache/#set-a-base-url
'base_url' => '/images/',
// Response class for serving images. If unset (default) an instance of
// \ADmad\Glide\Response\PsrResponseFactory() will be used.
// http://glide.thephpleague.com/1.0/config/responses/
'response' => null,
]);
EventManager::instance()
->on(
'FileManager.Fichiers.afterDelete',
function (Event $event) {
$server = \League\Glide\ServerFactory::create(Configure::read('ADmad/Glide.server')); // Use the Glide server config above
$file = $event->getData('file');
$server->deleteCache(Configure::read('ADmad/Glide.server.base_url') . $file->url);
}
);
}
);
I'm trying to add twig-view in slim v4
In slim v3, we add twig-view in container
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('path/to/templates', [
'cache' => 'path/to/cache'
]);
// Instantiate and add Slim specific extension
$router = $c->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
but I can't add twig like that in slim v4
Update: Twig-View has reached a stable version and the docs are updated to address Slim 4 integration.
If you are still using an unstable version of Twig-View, please consider upgrading.
First, you need to add Twig-View package to your project:
composer require slim/twig-view
And assuming the following directory structure:
composer.json
cache/
public/
|--index.php
templates/
|--hello.twig
vendor/
|--autoload.php
The followings are two working examples:
If you use a container (which is optional according to Slim 4 docs), you can add Tiwg creation definition to the container and use it when required. (I'm using php-di/php-di in this example, but you can use any PSR compatible dependency container.)
index.php, using a container:
<?php
use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/../vendor/autoload.php';
// Create Container
$container = new Container();
AppFactory::setContainer($container);
// Set view in Container
$container->set('view', function() {
return Twig::create(__DIR__ . '/../templates',
['cache' => __DIR__ . '/../cache']);
});
// Create App
$app = AppFactory::create();
// Add Twig-View Middleware
$app->add(TwigMiddleware::createFromContainer($app));
// Example route
$app->get('/hello/{name}', function ($request, $response, $args) {
return $this->get('view')->render($response, 'hello.twig', [
'name' => $args['name']
]);
});
// Run the app
$app->run();
You can also skip the container creation, but in that case you need to create the Twig instance before trying to render a template.
index.php, without a container:
<?php
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/../vendor/autoload.php';
// Create App
$app = AppFactory::create();
// Create Twig
$twig = Twig::create(__DIR__ . '/../templates',
['cache' => __DIR__ . '/../cache']);
// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));
// Example route
// Please note how $view is created from the request
$app->get('/hello/{name}', function ($request, $response, $args) {
$view = Twig::fromRequest($request);
return $view->render($response, 'hello.twig', [
'name' => $args['name']
]);
});
// Run the app
$app->run();
hello.twig:
Hello {{ name }}
Now try visiting /hello/slim4 in your browser and the output will be:
Hello slim4
SlimTwigView is at 3.0.0 beta (at least as of October 12, 2019), and some things have changed. The few online tutorials I've seen, as well as the official documentation no longer work.
TwigMiddleware no longer takes an instance of the $container as an argument, so you must first put Twig on the Container manually such as:
$container->set('view', function() {
// Of course put correct path to your views here
return new Twig('../views', ['cache' => false]);
});
You then you can add TwigMiddleware to your Slim App using the class' new createFromContainer method, like so:
$app->add(TwigMiddleware::createFromContainer($app));
// which is equivalent to:
// $app->add(TwigMiddleware::createFromContainer($app, 'view'));
At that point, you can render a Twig view like so:
$app->get('/', function (Request $request, Response $response, $args) {
return $this->get('view')->render($response, 'home.twig');
});
When using the Slim specific middleware, you now have access to the additional Twig extensions:
url_for
full_url_for
is_current_url
current_url
get_uri
Well! In my case I was using Slim 4.0 and Twig ^2.5. All I added to my code was
$container->set('view', function () use ($container) {
$view = new \Slim\Views\Twig(
__DIR__ .'/Templates'
, [ 'cache' => false ] //you can turn on caching by providing string path to cache or set to false
);
return $view;
});
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 am trying to add some Hooks to my OwnCloud app called Metadata, and i can't seem to figure it out (the hook is not being fired).
I tried following the content https://doc.owncloud.org/server/8.2/developer_manual/app/init.html and https://doc.owncloud.org/server/8.2/developer_manual/app/hooks.html (although it seems like the second one is outdated).
Basically all i am trying to do for now is the catch the pre-rename hook and write something to a file.
My code is :
myapp/appinfo/app.php
namespace OCA\Metadata\AppInfo;
use OCP\AppFramework\App;
$app = new App('metadata');
$container = $app->getContainer();
$container->query('OCP\INavigationManager')->add(function () use ($container) {
$urlGenerator = $container->query('OCP\IURLGenerator');
$l10n = $container->query('OCP\IL10N');
return [
// the string under which your app will be referenced in owncloud
'id' => 'metadata',
// sorting weight for the navigation. The higher the number, the higher
// will it be listed in the navigation
'order' => 10,
// the route that will be shown on startup
'href' => $urlGenerator->linkToRoute('metadata.page.index'),
// the icon that will be shown in the navigation
// this file needs to exist in img/
'icon' => $urlGenerator->imagePath('metadata', 'app.svg'),
// the title of your application. This will be used in the
// navigation or on the settings page of your app
'name' => $l10n->t('Metadata'),
];
});
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OC\Metadata\Hooks', 'postRename');
and then myapp/hooks.php
<?php
namespace OCA\Metadata;
use OC\Files\Filesystem;
use OC\Files\View;
class Hooks {
// private $userManager;
public static function postRename($params) {
file_put_contents("/var/www/data/owncloud_print2.log", "post_rename");
}
}
nothing ever gets written to the file. i have also tried other approaches all with no luck. anyone knows what i am doing wrong??
my connecthook was wrong. it should be:
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Metadata\Hooks', 'postRename');
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) {
});