I am working on creating a simple MVC inspired framework (for learning purposes and because i don't want to use a pre-existing framework at the moment). I have the system already set up and its working as it should, but i would like to have some feedback on the "view" part of the system, maybe i have set it up in a way that will prove to be inefficient in the future if the app grows, and maybe there is just a better way of doing what i am doing.
A little bit about how i set up the "framework":
When a user goes to a url, for example /posts/post_id, the file that is loaded is index.php, this file instantiates a router file, the router instantiates the required controller (and method if set) based on the url. The controller works with the relevant model to get data from the database (in this example, the post data), and then the controller sends that data off to the view class. The controller also sends the "view settings" to the view class.
What i mean by view settings and my use of it and view data:
The way i have set up the "View" part of this system is to be able to render either an entire page, which includes the template (header, footer, sidebar, etc.), or to render just a single html file (without the header, footer, etc.).
To do this, i send from the controller to the view class the following settings:
- The view settings - what navigation menu to show, if to show a sidebar and its location on the page (left, right, none), if to render just a file with html without the whole template (e.g. just a post, or a form), or a whole page with the template.
- The view data - the actual data needed for the view, for example the post data.
class View{
/* $viewData is sent from the controller, it contains all of the data needed
* for the view, including what i call the "view settings" as described above */
public function __construct($viewData){
//Instantiate a new error for this view (error handling class)
$this->err = new ErrorClass(get_class($this));
//Instantiate a new helper (helper functions used in the view)
$this->helpers = new ViewHelpers();
/* Save variables from the $viewData array */
//If a single file was sent to render (receives the file name and is rendered later)
$this->viewFile = $viewData['view_file'];
//If a whole page was sent to be rendered (this will render the whole template also)
$this->viewName = $viewData['view_name'];
//Template data, only used if a whole page should be rendered
$this->templateData = $viewData['template_data'];
//The data for the view, e.g. post data
$this->viewData = $viewData['view_data'];
//Call the render view method
$this->renderView();
}
/* Function to render the view output
===============================================*/
private function renderView(){
//If a single file should be rendered
if($this->viewFile && file_exists(VIEWS_PATH.$this->viewFile)){
require(VIEWS_PATH.$this->viewFile);
//If a whole page should be rendered
}elseif($this->viewName && file_exists(TEMPLATE_FILE_PATH)){
require(TEMPLATE_FILE_PATH);
//Save an error
}else{
echo 'Oops, something went wrong, we are looking into it!';
$this->err->setError(array('err_cat' => 3, 'err_msg' => "View wasn't able to load"));
}
}
}
A note about VIEWS_PATH
and TEMPLATE_FILE_PATH
:
VIEWS_PATH
is the path to the folder that contains all of the html files, when i use require(VIEWS_PATH.$this->viewFile);
i am including the file name that was sent from the controller, so this line would be: require('/app/views/post_form.php');
for example.
TEMPLATE_FILE_PATH
is a constant that equals the path to a main template file, what i mean by this is TEMPLATE_FILE_PATH
= /public/template/template.php
, and this file includes in it the header, the footer, and the actual main page that is needed, for example if loading a post form, the page would include the header, then the post form file, and then the footer.
EDIT: I understand that my initial question was not very clear, so i edited it, hopefully this is clearer.
elseif
statement, how is$this->viewName
related toTEMPLATE_FILE_PATH
? Maybe some value examples for the variables will make the whole picture clearer. And the constructor, it would be of much help to post it too. \$\endgroup\$UI\Web\View\Users\AddUser
orUI\Web\View\Users\ListUsers
. This class should be able to load and render a certain template file, like<project-root>/web/src/templates/templates/Users/add-user.html.twig
or<project-root>/web/src/templates/templates/Users/list-users.html.twig
. So, a specific controller would call therender()
method of a specific view instance, which will load and render a specific template file. To remember is, that a view should not be confused with a template file (or, short, template). \$\endgroup\$.twig
extension denotes the fact that a template engine (like Twig) can be used, in order to render the template files. In such a case, an instance of it would be injected into the specific view object. \$\endgroup\$