We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Multiple module layout

I'm using just getting started with Phalcon 2.0.0, and I'm trying to organize my site with multiple modules. I followed the example at https://docs.phalcon.io/en/latest/reference/applications.html#multi-module almost exactly, the only difference being that I named the two modules "default" and "temple" rather than "frontend" and "backend" (yes, I updated all the references in the code, as well). However, whenever I attempt to call the Temple module's index page (www.example.com/temple), the default index page is returned every time. Why would that be?

edited May '15

Hi!, in your index:

        $application->registerModules(
            array(
                'public' => array(
                    'className' => 'Frontend\Module',
                    'path' => '../app/frontend/Module.php'
                ),
                'private' => array(
                    'className' => 'Backend\Module',
                    'path' => '../app/backend/Module.php'
                ),
                'common' => array(
                    'className' => 'Common\Module',
                    'path' => '../app/common/Module.php'
                )
            )
    );
    $response = $application->handle()->getContent();

after, create a file called Module.php into the folder for the module, example:

app/common/Module.php
app/frontend/Module.php
app/backend/Module.php

and in every Module define:

<?php

    namespace Frontend;

    use Phalcon\Mvc\Dispatcher,
        Phalcon\Mvc\View,
        Phalcon\Mvc\ModuleDefinitionInterface;

    class Module implements ModuleDefinitionInterface {

        /**
         * Register a specific autoloader for the module
         */
        public function registerAutoloaders(\Phalcon\DiInterface $di = null) {

        }

        /**
         * Register specific services for the module
         */
        public function registerServices(\Phalcon\DiInterface $di) {
            //Registering a dispatcher
            $di->set('dispatcher', function () use ($di) {
                $dispatcher = new Dispatcher();
                $dispatcher->setDefaultNamespace("Frontend\Controllers");
    //            $dispatcher->setEventsManager($di->get('eventsManager'));
                return $dispatcher;
            });

            //Registering the view component
            $di->set('view', function() {
                $view = new View();
                $view->setViewsDir(APP_PATH.'app/frontend/views/');
                $view->registerEngines(array('.volt' => 'voltService'));
                return $view;
            });
        }

    }

don't forget, change, the namespace's name, reference name.

you folder app:

app/frontend controllers views

app/backend controllers views models , etc...

and in your route: something like:

$di->set('router', function () {
        $router = new Router(false);
        $router->setDefaultModule("backend");
        $router->setDefaultAction('index');
        $router->notFound(array(
            'module' => 'common',
            'controller' => 'error',
            'action' => 'index',
            'params' => '0404'
        ));

        $router->add('/', array(
            'module' => 'public',
            'controller' => 'login',
            'action' => 'index',
        ));
        $router->add('/:module/:controller', array(
            'module' => 1,
            'controller' => 2,
            'action' => 'index',
        ));
        $router->add('/:module/:controller/([a-z]+)\.(json|html)/:params', array(
            'module' => 1,
            'controller' => 2,
            'action' => 3,
            'type' => 4,
            'params' => 5
        ));
        $router->add('/:module/:controller/([a-z]+)\.(json|html)', array(
            'module' => 1,
            'controller' => 2,
            'action' => 3
        ));
        return $router;
    });

Try!, ;)

Hugo, I tried the solutions you suggested, but I'm still getting the default index page no matter what URL I provide. I can't even get to the 404 error when I provide a URL to a module that doesn't exist. You can see my code at https://github.com/farstrider/phalcon.farstrider.eu and the results at https://phalcon.farstrider.eu

edited May '15

in your index add at top:

    error_reporting(E_ALL);

to see errors,

I fork your project, and fixed the problem!, try now ;)!

I merged your changes, but navigating to the temple module (phalcon.farstrider.eu/temple) still returns the default index page. Even when I try to produce a 404 error -- by navigating to phalcon.farstrider.eu/notfound, for instance -- the default index page is displayed rather than an error page.

your virtual hosts is oks? this is mine, for your app:

    <VirtualHost *:80>
    ServerName helping
    ServerAlias helping.common
    DocumentRoot "/var/www/helping/public"
    <Directory "/var/www/helping/public">
    Options -Indexes +FollowSymLinks +Multiviews
    AllowOverride None 
    FileETag none
    RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]

    Header set Access-Control-Allow-Origin "*"
    #Header set Access-Control-Allow-Credentials: "true"
    SetOutputFilter DEFLATE
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    SetEnvIfNoCase Request_URI \
     \.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g)$ no-gzip dont-vary    

    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    Header append Vary User-Agent env=!dont-vary

    # Turn on Expires and set default to 0
    ExpiresActive On
    ExpiresDefault A0

    # cache por 1 año
    <FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
    ExpiresDefault A29030400
    Header append Cache-Control "public"
    </FilesMatch>

    # cache por 1 Mes
    <FilesMatch "\.(gif|jpg|jpeg|png|swf)$">
    ExpiresDefault A2592000
    Header append Cache-Control "public"
    Header set Cache-Control "max-age=31536000, public"
    </FilesMatch>

    # cache por 1 Mes
    <FilesMatch "\.(xml|txt|html|js|css)$">
    ExpiresDefault A2592000
    Header append Cache-Control "proxy-revalidate"
    Header set Cache-Control "max-age=31536000, public"
    </FilesMatch>

    # no hacer cache
    <FilesMatch "\.(php|cgi|pl)$">
    ExpiresActive Off   
    </FilesMatch>
    </Directory>    
    ##ServerAlias www.dummy-host.localhost
    ErrorLog "/var/log/helping-error.log"
    CustomLog "/var/log/helping.-access.log" combined
</VirtualHost>

Yes, my virtual host is set up properly. The only part that might be an issue is my rewrite rules:

<IfModule mod_rewrite.c>
    RewriteEngine   On
    RewriteCond     %{REQUEST_FILENAME} !-d
    RewriteCond     %{REQUEST_FILENAME} !-f
    RewriteRule     ^(.*)$          index.php   [QSA,L]
</IfModule>

In theory, this should produce URLs such as: www.example.com/module/controller/action/param1/param2 (as it does with Zend Framework).

I tinkered with the code some more, but it's still not working. The default index template is always returned, regardless of the URL entered. To me, this is a clear indication that, for some reason, the routes are not being properly parsed.

edited May '15

in my pc: when i go to:

https://helping/temple

the response:

Test! Temple

For you what response?

When i try:

https://helping/notfoundpage

the response:

There was an error!

for you?

You can see my results at https://phalcon.farstrider.eu As you can see, the same page is returned no matter how you change the URL.

You can see my rewrite rules above, and the Virtual Host I'm using is as follows:

<VirtualHost *:80>
        ServerName phalcon.farstrider.eu
        DocumentRoot /home/farstrider/www/farstrider.eu/phalcon/public/

        CustomLog /home/farstrider/logs/farstrider.eu/phalcon/access_log combined
        ErrorLog /home/farstrider/logs/farstrider.eu/phalcon/error_log

        SetEnv APPLICATION_ENV "production"
        <Directory "/home/farstrider/www/farstrider.eu/phalcon">
                Order deny,allow
                Deny from all
        </Directory>
        <Directory "/home/farstrider/www/farstrider.eu/phalcon/public">
                DirectoryIndex index.php
                AllowOverride All
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>


1.1k
Accepted
answer

Sigh. It was the rewrite rules. If I change the rule to the following, everything works as expected:

<IfModule mod_rewrite.c>
    RewriteEngine   On
    RewriteCond     %{REQUEST_FILENAME} !-d
    RewriteCond     %{REQUEST_FILENAME} !-f
    RewriteRule     ^(.*)$          index.php?_url=/$1   [QSA,L]
</IfModule>