For my Codeigniter site, I started by making a view for each controller situation. This was impractical, as it would require going back to the code for each to make a change. So I changed approach and operated on a 'default' controller with optional fields. I then thought I could load special views as needed into it.
I put together this view with optional fields with fields for $title, $search_bar on/off etc. However, now came the content area. I was able to load more views into this default view using:
$data['content_views'][]='blocks/login';
$this->load->view('default/a', $data);
and in the 'default'view:
if(isset($content_views)&& (is_array($content_views)))
{
foreach($content_views as $content_view)
{
$this->load->view(&$content_view);
}
}
(and that works fine)
Two questions:
Am I making things to complex? Is this an accepted way of doing this? Or have I misunderstood the functioning of a view and how they are intended to work?
I want a way to mix the $content_view, i.e. a block of text, then a view. I'm not quite sure as to how to proceed. Say I want a message first, then a view, then more text. This method will only accept views.
Can anybody help me create this flexible approach?
Yeah I would say you're making things a little complex. While I may not be following your description well enough to know precisely how to respond, I can tell you how I do it:
First the whole site is run through a template so the header and footer are the container file and all views needed within the site are rendered as page type views - like an article page, a gallery page, etc. Components are loaded and passed to the views as strings:
$content['sidebar'] = $this->load->view('components/sidebar', $data, true);
That last true says to render as string.
Essentially, this means the page views are pretty much html with php echoing out the necessary elements. No views calling other views, which is how I read your example.
CI loads views progressively, so your controller can output like so:
$this->load->view('header', $header_data);
$view_data['sidebar'] = $this->load->view('components/sidebar', $sidebar_data, true);
$this->load->view('content', $view_data);
$this->load->view('footer', $footer_data);
and in content view, handle the sidebar like so:
<?php if(isset($sidebar)): ?>
<nav>
<?php echo $sidebar; ?>
</nav>
<?php endif; ?>
And, assuming you populate those arrays for each view it will render header, then content, then footer. And also render sidebar if it is present.
So combining everything, I'm basically saying you can load in sections in your controllers progressively, passing sub-views as strings to whichever section makes sense. That keeps your view controlling in the controller where it belongs and not in the view files themselves. In my experience, I have not had to write a site that was so complex that this construct wasn't perfectly suitable if the site is planned well.
Related
Right now I'm simply sending the data to my page template but I don't think it's good to have all that logic together with the markup with the page, especially since I want to have multiple forms on the page which would lead to even more code that isn't really relevant to the view of the page. In another cms (concrete) I have set up routes that point to a custom controller to handle the form data, can I do something similar or is there a different approach for this in wordpress?
I would start by separating controller logic from the html template. Look at Timber for example: https://github.com/timber/timber
Then your page template will look more like a controller and you could avoid messy code from handling everything in one file.
Your page template could look like this:
<?php
$data = Timber::get_context();
$data['page'] = $page;
if (isset($_POST['whatever']))
{
$data['whatever'] = 'It works!';
Timber::render('views/whatever-posted.twig', $data);
}
else
{
Timber::render('views/landing.twig', $data);
}
IMO it is much cleaner code than mixing up PHP/HTML
I am trying to create a module which has both frontend and backend functionality. Like I need to ask for the city in the home page when the store loads. And all the available cities are entered/managed in backend admin panel.
Before I used to write for only backend things, frontend seems little confusing.
There is a design folder which is completely for theme development.
All the example are little different(https://www.mageplaza.com/magento-2-module-development/,http://inchoo.net/magento-2/how-to-create-a-basic-module-in-magento-2/]2), they have routes.xml, where route_id, and all are defined, but here I don't need any extra route. Need some additional tweaks in frontend pages.
I created module V_name/M_name/adminhtml/block controllers etc view ...
Guide me how to create a module, which has both front end and backend connection, cities should be entered in admin, they should show on the frontend homepage.
For now, I only managed to edit home page content CMS page by adding some HTML which shows a popup with a dropdown for cities when the page loads.
Since you already have the back-end figured out I will focus on front-end. Also, since all you need to do is populate a list that you already have created this should be easy. I did something like this before and I found it easier to just use JSON to query a list of, in your case the cities, and populate the drop down. I don't believe this is the most 'MVP/proper' way to go, but it is less work then the other ways. (At least for me it is. I always prefer the JavaScript option since it allows for easy future page customization.)
To use the JSON method you need to create a Block with a method like the one below. You will see that you will also have to create a Resource Model (I'm not going to go over creating the Resource Model or the details of Blocks since there are much better resources than me already online that will go into every single detail you need.). Once this is complete you can access the data straight from the .phtml page in an easy to use JSON array.
First you need to make sure you are now structuring your Modules properly. The new Block below should be in a structure like this...
app/code/<VENDOR>/<MODULE>/Block/Wrapper.php (or whatever you name it)
The admin Blocks should be in the structure below, which it sounds like you are already know how to do.
app/code/<VENDOR>/<MODULE>/Block/Adminhtml
Create your Block and add a method to create a JOSN array like below...
public function getCityList()
{
$city_array = array();
/** #var \<VENDOR>\<MODULE>\Model\ResourceModel\City\Collection $collection */
$collection = $this->_cityCollectionFactory->create();
$collection->addFieldToFilter('active','1')->addFieldToSelect(['city_id', 'city']);
$collection->getSelect()->order(array('city ASC', 'city_id ASC'));
$count = 0;
foreach ($collection as $model)
{
$city_array["$count"] = $model->getData();
$count++;
}
return \Zend_Json::encode($city_array);
}
FYI... The foreach loop in the code above is weird and uses $count because I needed to do some tricky things to get something to work.
Then you can create the Block in your .phtml file to access the data via javascript.
<?php
$block_obj = $block->getLayout()->createBlock('<VENDOR>\<MODULE>\Block\Wrapper');
?>
<script type="text/javascript">
window.citylistJson = <?php echo $block_obj->getCityList() ?>;
</script>
I was working on a site in which on right side I am displaying some fixed type of dynamic content like event calendar, login, register etc. right side bar name is right_view.php
So first I was doing like this that I was sending parameters in every function of controller's and then in my view I was accessing right side parameters by calling right view like this
<?php $this->load->view('right_view');?>
then after login I can get my username that is stored in session.
After that I thought it is not a good approach to send parameters in every functions I just make a controller named right.php and in this controller I am passing parameters to right_view.php and after that in my view I changed my code for callig righr_view like this
<?php include(base_url().'right');?>
It display right content as I do above but one changed happen that I cannot access any of session stored variable in right side bar.
Is session does not work after including controller in view?
You're basically wanting to do a template system but going about it the wrong way. And for the record no I don't think you can (or at least should) be loading controllers into views like that.
What you want is a template file something like this:
<?php
$this->load->view('templates/header', $title);
$this->load->view('templates/sidebar',$sidebar_content);
$this->load->view('pages/'.$main_content);
$this->load->view('templates/footer');
?>
Call that template.php
Then in your controller you'd do something like this:
public function welcome()
{
$data['main_content'] = 'welcome';
$data['title']='Welcome to REfficient.com!';
$data['sidebar_content'] = 'sidebar/no_sidebar';
$data['additionalHeadInfo'] ='';
$this->load->view('templates/template',$data);
}
So if you look at the template file the first line is loading the header and including the title variable to insert into the page (header, sidebar, maincontent and footer are all their own separate PHP pages) and so on.
Now what I did (since my layout was very similar to yours) is my main sidebar file has an if statement that says if logged in show x, if not show login form.
Note - the additionalHeadInfo variable is so I can have includes like jQueryUI or something on an individual page without loading it on pages that don't need it.
I used Joomla 1.5 for a site that I developed for a gaming company. Part of the site consists of a character generater for the game that they developed. The issue is that users want to be able to print the character sheets off, without having the Joomla template surrounding it.
As for the specifics, I have the directphp extension installed, and the entire generator is written in PHP (with a little JavaScript to handle things that PHP can't). As the generator spans several dozen page calls, it made sense to store everything in $_SESSION. All of this works correctly. In an attempt to make the final sheet printer friendly, I tried redirecting the user to a page outside of Joomla (though on the same server, and even within the same folder) but I cannot access the $_SESSION data from this new page.
I have seen several posts (a few on this site) that point to loading the Joomla Framework and accessing it that way, which I have tried, but the data that I was looking for does not appear to be contained there. Has anyone come across this problem before, or know how to get to that data?
You are making this WAY harder than it needs to be. You don't have to write any additional code to accomplish what you are trying to do. In order to print our the component output without all of the Joomla template, you just append ?tmpl=component to your URLs and Joomla will display only to component output without any of the template. If you want to give it a custom stylesheet or anything special, you can also add in a template override by adding a file named component.php in your template folder.
In order to control the CSS per page, you can add Page Class Suffixes in the menu items. Then add this code to index.php so you can use them.
Somewhere in the head add this:
$menu = &JSite::getMenu();
$active = $menu->getActive();
$pageclass = "";
if (is_object( $active )) :
$params = new JParameter( $active->params );
$pageclass = trim($params->get( 'pageclass_sfx' ));
endif;
Replace your body tag with this:
<body id="<?php echo $pageclass ? $pageclass : 'default'; ?>">
Any page that you do not specific a Page Class Suffix for will use default as the body ID, any that you do will use what ever you specify.
i have a little problem that i dont know what to do with.
i have a template with
header
content
sidebar
footer
on all my page the only thing that need to change is the content, so how can i pass data to my sidebar/footer
do i need to make a controller? or do i need to make a library and load it in my template.php file?
i use this template system
http://williamsconcepts.com/ci/codeigniter/libraries/template/index.html
I am not sure about your specific Template Library, but I do know that generally this is done by nesting views inside other views, and as long as the data is loaded into the initial view, it propagates to nested views as well.
Example without Template library
Controller function
function index() {
$data['some_var'] = "some value";
$data['another_var'] = "another value";
$this->load->view('first_view',$data);
}
first_view
<? $this->load->view('header') ?>
<h1>Content</h1>
<? $this->load->view('sidebar') ?>
<? $this->load->view('footer') ?>
In this instance, the $data that is loaded into first_view propagates to header,sidebar,and footer.
So you can use $some_var or $another_var in any of these views.
UPDATE
Another way you can load data in to your views globally is with this function
$this->load-vars($data);
Where $data is your view data, this statement just before you load your template should allow all of this data to be accessed in any view loaded by the template. While this is a shotgun approach, it is the suggested way to do this by your chosen template library.
If you will only ever change content, then there is no need to set up regions for your header, sidebar or footer - just add their contents to your main template file.
However if you will infrequently need to change the content of these regions, I would create "default" views for these regions, and load in each controller constructor, like thus:
$this->template->write_view('header', 'default/header');
$this->template->write_view('sidebar', 'default/sidebar');
$this->template->write_view('footer', 'default/footer');
You can then either extend these default region views or overwrite them on a per method basis (refer to the documentation of your library to find out how).