1

Lets say my component is called dumbo. It contains all kind of MVC stuff and works well. Now i have a second component that is called jumbo. I need both components to share some models, controllers and views (and other stuff) from a central library.

Of course this is helpful regarding that question:

https://docs.joomla.org/Using_own_library_in_your_extensions/en

But it seams i have done something wrong.

I have setup a namespace loader:

JLoader::registerNamespace('Mylib',  JPATH_LIBRARIES  . '/mylib');

Here comes an example model and view from the central library that dumbo and jumbo should share and use:

Directory the model is in:

.\libraries\mylib\listings\model.php

The model itself:

defined('_JEXEC') or die;

use Joomla\CMS\MVC\Model\ListModel;  

class MylibListingsModel extends ListModel
{
    public function __construct($config = array())
    {
        echo "lib model";
        parent::__construct($config); 
    }

    ...
}

Directory the view is in:

.\libraries\mylib\listings\view.php

The view itself:

defined('_JEXEC') or die;

use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;

class MylibListingsView extends JViewLegacy
{
    protected $items;
    protected $pagination;
    protected $state;

    public function display($tpl = null) 
    {
        echo "lib view";
        parent::display($tpl); 
    }

    ...
}

When calling the listings view from the dumbo component like this:

127.0.0.1/dumbo/administrator/index.php?option=com_dumbo&view=listings

The library structures are not found (View not found [Name, Typ, Präfix]: listings, html, dumboView)

I also added the JLoader::registerPrefix('Mylib', dirname(__FILE__)); into a system plugin (onAfterInitialise Event) without luck.

What am i missing? Thanks!

4
  • Looks like you forgot to add actual views in your components.
    – Sharky
    Oct 13 '20 at 5:21
  • I want the views to be taken from the library. If i add views in the component, that extend from the library views, the model getItems() is getting called twice.
    – Mike
    Oct 13 '20 at 8:47
  • Hi, first of all it's quite a strange requirement, usually you would use models from a library not views; that said, I don't think you can achieve it. Registering the namespace only tells Joomla where to find Mylib- but as you see in the error message "View not found" the view it's looking for is supposed to be called dumboView. If you want automatic view selection from Joomla, I would use the library as the entry component and let it invoke the models from dumbo and jumbo. Else you could add a task to the controller which explicitly loads the view Oct 13 '20 at 20:30
  • Thanks for your answer. Loading views from the library over the controller is what i done previously. I was just looking for a more clean way. atm i have proxy component views that extend from the library views, but i was looking for a way to have as few elements in the components itself as possible.
    – Mike
    Oct 14 '20 at 8:54
1

First of all, you're using different file structure and class naming conventions than Joomla! core. This won't work without rewriting related methods such as controller's getView().

That said, using standard naming conventions, I was able to get this to work by setting base_path option when fetching the controller in component's entry file:

$controller = JControllerLegacy::getInstance('Mylib', ['base_path' => JPATH_LIBRARIES . '/mylib']);

This loads the main controller named MylibController and located in libraries/mylib/controller.php. Models and views are then loaded correctly from within the component.

However, there could be many issues using a library like this. For instance, if it contains controllers extending from Joomla\CMS\MVC\Controller\FormController, you must set $option property to the name of the component currently being used (e.g. com_dumbo, you can get this from the input). Otherwise, library prefix mylib will be used to build redirect links which results in broken links.

3
  • I already have a library containing working MVC structures for different components. You can use every filestructure that makes sense in the library while registering via jloader. e.g. JLoader::register('MylibFrontendViewListings', MYLIBPATH_FRAMEWORK . '/frontend/views/listings.php'); Controllers are getting used directly from the library. The question was if for example views can be used from the library without extending like this: class DumboViewListings extends MylibFrontendViewListings {}. Just to get everything a bit leaner.
    – Mike
    Oct 15 '20 at 13:30
  • Having to manually register every class is not an acceptable solution for me. But whatever works for you.
    – Sharky
    Oct 16 '20 at 16:35
  • Thats the way kunena does it for example. Accessing the component name via input is a bad idea, because there is a lot REST stuff going on and the component is not always in GET. It can be just defined via constant on component level. So its possible, i was looking for a leaner way. Still thanks for the try.
    – Mike
    Oct 16 '20 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.