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.
Related
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
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 am a Drupal newbie. I have written a custom module in Drupal 8 and it works and displays some content.
I want to add a tab in the user's profile that links to my custom module.
As far as I understand, I need to write a route and a task. This is what I have done :
my_module.routing.yml
my_module.some_route_name:
path: '/user/{user}/some_path'
defaults:
_controller: '\Drupal\my_module\Controller\MyModuleController::content'
_title: 'Some Title'
requirements:
_permission: 'access content'
options:
user: \d+
my_module.links.tasks.yml
my_module.some_task_name:
route_name: my_module.some_route_name
base_route: entity.user.canonical
title: 'Some Title'
I have done this and the route works as it should, however no tab shows up in my user's profile page.
It should look something like this :
Edit 1
I have partially resolved the issue by creating a hook as per Drupal API 8.6 (menu_local_tasks_alter) and this is what I wrote :
function my_module_menu_local_tasks_alter(&$data, $route_name, \Drupal\Core\Cache\RefinableCacheableDependencyInterface &$cacheability) {
$url = Drupal\Core\Url::fromRoute('my_module.some_route_name');
if ($route_name == 'entity.user.canonical') {
$data['tabs'][0]['my_module.some_route_name'] = [
'#theme' => 'menu_local_task',
'#link' => [
'title' => t('Some Title'),
'url' => $url,
'localized_options' => [
'attributes' => [
'title' => t('Add content'),
],
],
],
];
// The tab we're adding is dependent on a user's access to add content.
$cacheability
->addCacheTags([
'user.permissions',
]);
}
}
This works if I replace the {user} part of my route's path with 1. When I have {user} in the path, it now complains with the following error :
The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\Routing\Exception\MissingMandatoryParametersException</em>: Some mandatory parameters are missing ("user") to generate a URL for route ...
Edit 2
I have also made sure to provide my content method in my controller with a user object $user that implements AccountInterface as described here: https://www.drupal.org/docs/8/api/routing-system/using-parameters-in-routes , however, I still get the same error message.
You don't need the hook, I just tested with your routing and _task definitions and it works fine for me.
This is my controller:
class MyModuleController {
public function content($user) {
return [
'#markup' => "user: $user"
];
}
}
This renders as: "user: 1" at the "/user/1/some_path" URL.
I think you are also trying to use Drupal's automatic paramater upcasting, but that is optional.
MissingMandatoryParametersException
To solve the exception (Symfony\Component\Routing\Exception\MissingMandatoryParametersException).
You have to add the mandatory parameter in your route. Just add the user (['user' => 1]):
$url = Drupal\Core\Url::fromRoute('my_module.some_route_name', ['user' => 1]);
In case anyone stumbles on this in the future, here's an easier way that doesn't require the HOOK_menu_local_tasks_alter implementation, and corrects a typo in the OP's code:
my_module.routing.yml
entity.my_entity.my_route:
path: '/admin/my_entity/{my_entity}/my_route' # Or similar
defaults:
_controller: '\Drupal\my_module\Controller\MyController::content'
_title: 'My Route Title'
options:
parameters:
my_entity:
type: entity:my_entity
requirements:
_permission: 'my_permission'
my_module.task.yml
Note the singular task not tasks in the OP's post.
entity.my_entity.my_route:
route_name: entity.my_entity.my_route
base_route: entity.my_entity.canonical
title: 'My Route Title'
Then write your controller as you would in #cesar-moore's post, with the first parameter upcast, as he notes, as MyEntity $my_entity. No need for any alterations. This route will now show a new tab on every page of your entity: View, Edit, or similar.
Learning custom modules--I have made a "hello world" module and when searching using the words "hello world" (with or without quotes), it doesn't show up in the search results.
How can I make custom module content show up in the search results?
The reason I want this is because I am going to make a module that imports a bunch of word docs, that change continually (they upload to the server via owncloud), and I want them search-able. I am planning on making a custom module to handle this process. The reason I mention it is because I might not be going about this correctly. I am assuming it is the correct use of a module and the best way to go about implementing this need.
EDIT (adding code)
Controller:
$ cat src/Controller/HelloWorldController.php
<?php
namespace Drupal\hello_world\Controller;
class HelloWorldController {
public function myCallbackMethod() {
$element = array(
'#markup' => '<p>Hello World</p>',
);
return $element;
}
}
info yaml file:
$ cat hello_world.info.yml
name: Hello World
type: module
description: 'A basic Drupal 8 Hello World Module.'
package: Custom Modules
version: 1.0
core: 8.x
module file:
$ cat hello_world.module
<?php
use Drupal\Core\Routing\RouteMatchInterface;
function hello_world_permission() {
$permissions = array(
'administer hello world' => array(
'title' => t('Administer Hello World module'),
'description' => t('Change the settings for Hello World module.'),
),
);
return $permissions;
}
routing yaml file:
$ cat hello_world.routing.yml
hello_world.hello_page:
path: '/hello/world'
defaults:
_controller: '\Drupal\hello_world\Controller\HelloWorldController::myCallbackMethod'
_title: 'Hello World'
requirements:
_permission: 'access content'
first.form:
path: '/first/form'
defaults:
_form: '\Drupal\hello_world\Form\FirstForm'
_title: 'First Form'
requirements:
_permission: 'access content'
Every content in Drupal must be indexed in order to show in search results page. Indexing is one of the cron tasks in Drupal so you need to run cron after adding new content in order to show in search results. You can run cron manually or you can set up that cron runs automatically on some time interval.
Additional information you can find on Drupal cron.
Hope this helps.
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.