2
votes

I started building a drupal 8 custom module but not able to run it.Its displaying Page Not Found Error.

Name of my module is my_form,here is my_form.module file

 <?php
 function my_form_menu() 
 {
 $items = array();
 $items['hello'] = array(
'title' => 'Hello World',
'description' => 'This is my First page.',
'route' => 'my_form.hello',
 //'type' => MENU_LOCAL_TASK,
 );
$items['form'] = array(
'title' => 'First form',
'description' => 'This is a example form.',
'route' => 'my_form.formpage',
//'type' => MENU_LOCAL_TASK,
);
return $items; 
}
?>

here is my_form.routing.yml file

<?php
my_form.hello:
path: 'my_form/myformcontroller'
defaults:
_controller: '\Drupal\my_form\Controller\myformcontroller::hello'
_title: 'My first form in Drupal 8'
requirements: 
_permission: 'access content'


my_form.formpage:
path: 'my_form/form'
defaults:
_form: '\Drupal\my_form\Form\form'
_title: 'Form page'
requirements:
_permission: 'access content'

?>

I think he main conflict is this file, please tell if there is problem with the routing paths or naming.(i am still not sure if i have provided the correct path for the PATH field while defining the route.) here is the myformcontroller.php whose path is [module]\src\Controller\

 <?php
 namespace Drupal\my_form\Controller;
 class myformcontroller
 {
 public function hello()
 {
 $element['markUp'] = array(
 #markup' => 'Hello world!',
 );
 return $element;
 }
 }
 ?>

here is the form.php located at [module]\src\Form\form.php

 <?php
 namespace Drupal\my_form\Form;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Component\Utility\UrlHelper;
 class formpage extends FormBase {
 public function getFormId() {
 return 'my_form_formpage_form';
 }
 public function buildForm(array $form, FormStateInterface $form_state) {

 $form['name'] = array(
'#type' => 'textfield', 
'#title' => 'name',
'#required' => TRUE,  
 );
 $form['email'] = array(
'#type' => 'textfield', 
'#title' => 'email',
'#required' => TRUE,  
 );
    $form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Submit'),
 );
 return $form;
 }
 public function validateForm(array &$form, FormStateInterface $form_state) {
 $email = $form_state['values']['email'];
 if (!filter_var($email, FILTER_VALIDATE_EMAIL))
  {
    form_set_error('email', t('Invalid email format'));
  }
  }
  public function submitForm(array &$form, FormStateInterface $form_state) {
     foreach ($form_state->getValues() as $key => $value) 
   {
     drupal_set_message($key . ': ' . $value);
   }
   }
   }
  ?>

Please help me out.

2
instead of using my_form.module for describing menu, menu items has to be defined in module_name.links.menu.yml file https://www.drupal.org/node/2122241 - pavlovich

2 Answers

1
votes

Basically this is all you need:

my_form.routing.yml:

my_form.formpage:
  path: '/my_form/form'
  defaults:
    _form: '\Drupal\my_form\Form\MyForm'
    _title: 'Form page'
  requirements:
    _permission: 'access content'

my_form.info.yml:

name: My Form
type: module
description: My form module.
core: 8.x

MyForm.php (location is my_form/src/Form/MyForm.php):

<?php

namespace Drupal\my_form\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class MyForm extends FormBase {

    public function getFormId() {
        return 'my_form_formpage_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state) {

        $form['name'] = array(
            '#type' => 'textfield',
            '#title' => 'name',
            '#required' => TRUE,
        );
        $form['email'] = array(
            '#type' => 'textfield',
            '#title' => 'email',
            '#required' => TRUE,
        );
        $form['submit'] = array(
            '#type' => 'submit',
            '#value' => t('Submit'),
        );
        return $form;
    }

    public function validateForm(array &$form, FormStateInterface $form_state) {
        $email = $form_state['values']['email'];
        if (!filter_var($email, FILTER_VALIDATE_EMAIL))
        {
            form_set_error('email', t('Invalid email format'));
        }
    }

    public function submitForm(array &$form, FormStateInterface $form_state) {
        foreach ($form_state->getValues() as $key => $value)
        {
            drupal_set_message($key . ': ' . $value);
        }
    }
}

I have renamed form.php file to MyForm.php and used class MyForm inside. This is considered better practice (coming from Symfony and some other known frameworks) - using the same name both for class inside the file and the file name itself.

P.S. Do not forget also to enable the module you have created and clean the cache too.

0
votes

I have just had exactly the same problem. The issue for be was in the routing YAML. Drupal does not tell you about typo's in YAML!

module.add_thing:
  path: '/admin/config/development/module/add'
  default:
    _form: '\Drupal\module\Form\ModuleForm'
    _title: 'Add New Thing'
  requirements:
    _permission: 'administer module'

Let's play spot the typo!


Answer: default... should have been defaults. That s cost me 2 hours of development time.

I also lost 30 mins of dev time before this because the definition of another route (eg module.overview) was missing a trailing semi-colon.

Neither of these "syntax" style errors were reported by Drupal. Drupal did not complain about a missing semi-colon and it did not complain about missing defaults.