I integrated a vue.js SPA into a drupal site using a small module with a .routing.yml file and a class for the controller that displays the application.
Here is the code for the .routing.yml file and the controller
// Routing
jeu_comptabilite.formation:
path: '/ma-formation'
defaults:
_controller: '\Drupal\jeu_comptabilite\Controller\ComptabiliteController::app'
_title: ''
requirements:
_permission: 'access content'
// Controller
namespace Drupal\jeu_comptabilite\Controller;
use Drupal\Core\Controller\ControllerBase;
class ComptabiliteController extends ControllerBase {
/**
* #return array
*/
public function app(): array {
return [
'#markup' => '<div id="app"></div>'
];
}
When in drupal I go to the page https://my-site/my-formation it works. Then, if I don't navigate in the application (for example https://my-site/my-formation/page-1) it also works.
But if I type in the bar or if I reload the url https://my-site/my-formation/page-1 drupal does not know the page because the module only knows the url /my-formation
I guess there must be a way to control this with HttpFoundation but I don't know how.
How to manage the /my-formation/something urls without having to fill them all in the .routing.yml file
thank you
Related
I want to create route to return a simple text in custom module of drupal 9. Whenever I try to open a page it shows an error "Page not found The requested page could not be found."
Here is my code.
mymodule.info.yml
name: My First module
type: module
core_version_requirement: ^8 || ^9
description: 'My first module'
mymodule.routing.yml
myModule.Content:
path: '/mymodule'
defaults:
_controller: '\Drupal\myModule\Controller\FirstController::content'
_title: 'My First Page and Menu Item'
requirements:
_permission: 'access content'
FirstController.php
<?php
namespace Drupal\myModule\Controller;
use Drupal\Core\Controller\ControllerBase;
class FirstController extends ControllerBase{
public function content(){
return array(
'#type'=>'markup',
'#markup'=>t('This is menu linked with custom page'),
);
}
}
I have the feeling it has something to do with the way you named your module, which makes drupal not recognize the routes file.
What happens when you change the directory name and module name to my_module, rename your info file to my_module.info.yml and the routes file to my_module.routing.yml? That is also the proper naming convention.
I've installed Wordpress inside my Laravel app to manage blog content and other stuff.
Now I need user Laravel authentication for accessing wordpress. Is it possible to do that ? If yes, how?
As per my understanding you need Laravel authentication for accessing wordpress blog. Unauthenticated users should not be able to access it.
If this is the case. Solution is listed below.
Your Blog url: site_url/blog { it can be wordpress folder name inside laravel }
Edit ( routes/web.php )
Route::get('/blog', 'AdminPagesController#blog');
AdminPagesController
namespace App\Http\Controllers;
use Request;
use Carbon\Carbon;
class AdminPagesController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
//It will check if logged in, if not redirect to login page
$this->middleware('auth');
}
public function blog(){
// Simple return, wordpress will handle rest if authenticated person access the url
return;
}
}
The only way I can think of to make this work is reading the index.php from WordPress inside your Laravel controller with
ob_start();
require '/path/to/wp/index.php';
$html = ob_get_clean();
return response($html);
However if you want to use Laravel with a CMS, there are better (native) options like October CMS.
I am developing a custom module in Drupal 8. It shows data regarding some organizations that make use of our service. For this I have created a Controller that shows data from the database, which is put there by another module. From the scarce information and tutorials available on Drupal 8 developement I've been able to create the following. In the .routing.yml file I have created a path to this overview table like so (it doesn't properly copy here but the indents are okay):
OrganizationOverview.world:
path: '/world'
defaults:
_controller: 'Drupal\OrganizationOverview\Controller\OrganizationOverviewController::overview'
_title: 'World'
requirements:
_role: 'administrator'
_permission: 'access content'
So now the overview is accessible with the URL site.com/world. But what we want is to show it on the frontpage or show it anywhere else on the site. For this it needs to be a Block. For this I have created an OrganizationOverviewBlock class in OrganizationOverview/src/Plugin/Block/OrganizationOverviewBlock.php which is the proper way according to the PSR-4 standard. The class looks like this:
<?php
namespace Drupal\OrganizationOverview\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Session\AccountInterface;
/**
* Provides a 'OrganizationOverviewBlock' block.
*
* #Block(
* id = "organization_overview_block",
* admin_label = #Translation("OrganizationOverviewBlock"),
* category = #Translation("Custom")
* )
*/
class OrganizationOverviewBlock extends BlockBase
{
public function build()
{
return array(
'#markup' => 'Hello World',
);
}
public function blockAccess(AccountInterface $account)
{
return $account->hasPermission('access content');
}
}
So now it should show up in the Blocks Layout page (after flushing cache, which I do consistently) at site.com/admin/structure/block/ as "Organization Overview Block" where I should enable it, according to plenty sources (Create custom Block, Block API Drupal 8). But it doesn't show up there. I've tried implementing ContainerFactoryPluginInterface with some of those methods but that changes nothing. It does not show up. I've tried making a new test module with a block with the same code but a simpler name and it does not show up. I've copied the code to another platform (the production site) but it also doesn't show up there. What am I doing wrong? Can someone help me? I know Drupal 8 is new but this module really needs to be published soon.
You'll find a working example of building custom block in the Drupal Examples Project. So:
Get the Drupal 8 examples project
Enable the Block Example Module
Double check the working code
With that, you should get your block available in your own module
You can also take advantage of what explained here, where a single php file do the all job. Check files and folders path also.
Not require routing file for custom block.
<pre>
class TestBlock extends BlockBase {
/*
** {#inheritdoc}
*/
public function build() {
return array(
'#markup' => $this->t('Welcome page!'),
);
}
}
</pre>
http://drupalasia.com/article/drupal-8-how-create-custom-block-programatically
You should respect the Drupal coding standard recommendations:
No camelCase naming convention in module name.
OrganizationOverview actually is an error, you should use organization_overview (lowercase/underscore) naming conventions.
I've just installed Drupal and got to working with it and this problem is keeping me from moving forward. After browsing through what feels like too many solutions, I still couldn't find a fix for this. I followed the steps in the Drupal site + many others in creating a custom module but ultimately end up with a "Page Not Found" landing page - the page still has Drupal's layout but it's not reading the controller I have set.
The structure of my folder:
drupal
/modules
/custom
/sam
sam.routing.yml
sam.info.yml
sam.module
/src
/Controller
SamController.php
sam.routing.yml: (I'm kind of lost with this file, but I've been using spaces for indentation instead of tabs as I know yml files don't like tabs but I'm getting the feeling that Drupal isn't picking up on this routing.yml file. I did 2 spaces for the indentation)
sam:
path: '/sam'
defaults:
_controller: 'Drupal\sam\Controller\SamController::build'
_title: 'Sams Website'
requirements:
_permission: 'access content'
My controller:
<?php
namespace Drupal\sam\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
class SamController extends ControllerBase {
public function build() {
return array(
'#markup' => t('Hello World'),
);
}
}
I've checked the error logs in Apache and didn't really get any helpful messages. Is there something I'm missing?
You need the initial \ when specifying the fully qualified class name. Simply adjust your routing.yml to
sam:
path: '/sam'
defaults:
_controller: '\Drupal\sam\Controller\SamController::build'
_title: 'Sams Website'
requirements:
_permission: 'access content'
Otherwise it will not build the route as the class cannot be found.
In my Symfony2 app, I want to globally fetch a value from my database on each template and don't want to call on each Controller. I know I could define that as a service and inject that service into my twig templates (by defining it as a twig global).
Is that the common and recommended way? Or should I rather create an abstract Controller class where I fetch that value in my constructor and then inherit from all my other Controllers?
Note: It is actually not a static value that is the same for all users, but it is a user specific value which is different for each user.
If this variables are used to render the same spot on your page you can render an embedded controller. Like this:
<div id="sidebar">
{{ render(controller('YourBundle:User:stats')) }}
</div>
This will inject whole output of YourBundle/UserController/statsAction to the #sidebar div. Inside this action you can extract all inforamtion that you need.
If you need to use this variables in other way maybe you should look at response event.
Are you familiar with event listeners? http://symfony.com/doc/current/cookbook/service_container/event_listener.html
An event listener can be used to inject twig globals.
class ModelEventListener extends ContainerAware implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
KernelEvents::CONTROLLER => array(
array('doProject', -1300),
),
KernelEvents::VIEW => array(
array('doView', -2100),
),
);
}
public function doProject(FilterControllerEvent $event)
{
$project = $whatever_is_needed_to_find_the_project();
if (!$project) throw new NotFoundHttpException('Project not found ' . $projectSearch);
// Add to request
$event->getRequest()->attributes->set('project',$project);
// Give all twig templates access to project
$twig = $this->container->get('twig');
$twig->addGlobal('project',$project);
}
# services.yml
cerad_core__model__event_listener:
class: '%cerad_core__model__event_listener__class%'
calls:
- [setContainer, ['#service_container']]
tags:
- { name: kernel.event_subscriber }
If it's a user value like you said you can get app.user.XXX on every twig template you need without processing nothing ;)