Magento: how to add a link via code to a block of a custom module? - magento

I'm trying to add a link to one of my blocks to a specific action of one of my controllers. Looking through the class docs and googling didn't resolve something useful. (maybe I just used the wrong search queries).
My Controller has two actions:
indexAction() and exportAction()
Now, in one of my blocks I wand to add link to exportAction(). I've found the method addLink() but this doesn't work.
Maybe anyone knows how to do that ? Or could point me to the right resources on the net ?
Regards, Alex
Block Example:
<?php
class Polyvision_Tempest_Block_Adminhtml_View extends Mage_Adminhtml_Block_Template
{
public function __construct()
{
parent::__construct();
}
protected function _toHtml()
{
$html = "whatever";
return $html;
}
}
?>

Your question isn't clear/complete.
A block renders HTML, either through a phtml template or through PHP code. To add an HTML link, you just render a html anchor tag with an href
//via PHP
protected function _toHtml()
{
$html = 'My Link';
return $html;
}
//via phtml template
#your block
class Polyvision_Tempest_Block_Adminhtml_View extends Mage_Adminhtml_Block_Template
{
protected function _construct()
{
$this->setTemplate('path/to/from/template/folder/as/basetemplate.phtml');
}
}
#your template
My Link';
The addLink method is a special method that only applies to certain types of blocks. When you call it it add links information to the block's data properties. Then, it's _toHtml method or phtml template has been written such that it loops over the stored data to output links. It doesn't apply to general blocks, which is what makes your question confusing.
Hope that helps!

Related

CodeIgniter Dry Navigation

My boss told me make dry navigation dont use repetitive code, for navigation i am trying to extend CI_Controler and with construct load header nav, body, footer files.
My question is when i create new controller and when i try to load different view files, how to achive that???
my extended controler
class MY_Controller extends CI_Controller
{
public function __construct() {
parent::__construct();
$this->load->view('view_header');
$this->load->view('includes/nav_home');
$this->load->view('view_home');
$this->load->view('view_footer');
}
}
and later when i am creating new controler how to load diffrent view files
class Pages extends MY_Controller
{
public function __construct() {
$this->load->view('includes/nav_new_view');
$
}
}
You can create a template library yourself. For example :
function template($view_name,$view_data){
//below will return html string from view name
$data['content'] = $this->load->view($view_name,$view_data,true)
//load main template view and pass the html string to main template
$this->load->view('main_template',$data);
}
In main template, just echo $content
If I understand your question, you're trying to achieve a template situation. For this, the best way is to actually call your templates view files within a primary page view. What I mean is your controller function (not the constructor, an actual class function representing a page) should call a primary view such as
$this->load->view('page1', $this->data);
and within that file, you call
$this->load->view('nav', $this->data);
then your content and then
$this->load->view('footer', $this->data);
You would then repeat the process for page 2 where in your controller's page2 function, you would call
$this->load->view('page2', $this->data);
and your page2 view file is almost identical to page1 except you use your page 2 content in that area.
You could even use a single template view file and pass it a $content variable (which obviously changes per page) and call
$this->load->view('template', $this->data);

CodeIgniter - Including sections of code?

I have about 9 lines of code that will be the same in many of my controllers. They go in the index and are used to check whether the user is logged in, what level of access has been granted, and grab some session variables. What's the best way to include snippets of code that are not complete functions within themselves?
The snippets are not in all controllers, just the ones that build the admin section of the application.
It would be great if I could use one line of code to include the snippet but I'm new to CodeIgniter and I don't want to stray from best practices. If you could include a brief example that would help me visualize this. Thanks!
You want to create an extension of the base CI controller and do your checks there. Extending the cores are in the documentation here: http://ellislab.com/codeigniter/user_guide/general/creating_libraries.html Scroll down to the Extending Native Libraries part.
In your new controller you can do something like this:
<?PHP
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct(); //Gets all the CI_Controller functions and makes them available to this controller.
if($this->session->userdata('is_logged_in')
{
$this->load->model('categories');
$this->categories=$this->categories->getAllCategories();
}
}
}
Then in your other controllers you use MY_Controller instead of CI_Controller like this:
<?php
class Pages extends MY_Controller {
Obviously you'll have your own checks and variables to load but this should give you the general idea. In the example above I can now use $this->categories to retrieve my categories anywhere in the application that's been loaded with MY_Controller.
I'm using a 'main' template file (views/template.php):
// views/template.php
<?php $this->load->view('includes/header'); ?>
<?php $this->load->view('includes/' . $main_content); ?>
<?php $this->load->view('includes/sidebar'); ?>
<?php $this->load->view('includes/footer'); ?>
So the view directory structure is something like this:
--views
--includes
- header.php
- footer.php
- template.php
As you can see inside the view/includes/ folder I'm using some reuseable snippets like 'header.php', 'footer.php'...
So inside a controller I'm loading this main template file:
class MyController extends CI_Controller {
public function index()
{
//...
$this->load->view('template',$data);
}
}
So it loads 'template.php'.
And can use the $data inside header.php, footer.php too..
But you can vary this as you want, it's just a 'basic' idea..

Rendering a partial view in Zend for adding html to routing action layout

I am rendering a page with a lot of frames (XHR contentpanes via dojo). This is done through a request to IndexController which sets up regions 'header,left,right,center,footer' with the exception, that center is not filled in with contents. This in turn is set by calling PaneController in menu.onclick. Caveat; search engines indexing service does not get center region contents.. I wish to bypass AJAX loading of center, if user enters via /index/index.
Relevant snippets from IndexController:
class IndexController extends Zend_Controller_Action {
public function indexAction() {
$this->indexModel = $this->view->indexModel = new Application_Model_Index();
// Goal is to render "/pane/main/" action and capture the HTML
$this->view->mainPane = (string) $this->renderPaneMain();
return $this->render();
}
public function renderPaneMain() {
// ActionStack ?
// action() ?
return $HTML;
}
}
Relevant stuff in Pane
class PaneController extends Zend_Controller_Action {
public function preDispatch() {
// will only return a contentpane, dont render layout
if ($this->getRequest()->isXmlHttpRequest()) {
$this->_helper->layout()->disableLayout();
$this->view->doLayout = true;
}
}
public function mainAction() {
this.render("main.phtml");
}
public function init() {
$this->panesModel = new Application_Model_Panes();
$variant = $this->getRequest()->getParam('variant', '');
// routing variables need to be set, how?
if (empty($variant))
$this->_redirect('/');
}
}
Basically, i need the PaneController to _not render the global layout but call its .phtml view file, once it has been setup with relevant model entries and such.
Any ideas as to how I can achieve this in its most efficient form?
Very well, ill attach the workaround im using here
The forms and the fork-logic i have moved to the model that is coexisting with PanesController. For the IndexController, which will present the default Pane as inline HTML without AJAX - there is a couple of duplicated initializations going on.
So, IndexModel extends the PanesModel - without initializing it. In my index.phtml view (for Index action) i have following code to render the inline html from a pane.
in index controller
$this->view->model = new IndexModel(); // extends PanesModel
$this->view->model->setDefaultProperties($variant, $pagination, ...);
in index view:
$this->partial("panes/main/main.phtml", array("model", $this->model);
and from pane view:
<?php if($this->model->goThisDirection()): ?>
Switch 1 HTML contents
<?php endif; ?>
Caveat: I also had to not render any form of layout within the pane (dojox contentpanes allows for <script> and <style> tags) - and this ofc ripples to any other pane action of mine.

CodeIgniter - Autoload for views?

is there any way to load a view (for header or footer) on every function (in a controller)? I have a couple of if/else statements there and it would be a pain to change it all when I'll need to.
Yes, you can load the view in the __construct function at the top of your controller. Take
a look at the PHP manual on Constructors
function __construct()
{
parent::__construct();
$this->load>-view('your_view');
}
If the header and footer are going to be constant and required components for the visual part of your site, but you may want to load a different content portion between your header and footer, then you can make a function that will take an argument.
private function doViews($argument)
{
$this->load->view('header');
$this->load->view($argument);
$this->load->view('footer');
return NULL;
}
You may want to have an array of available views inside the doViews function in order to do proper validation that the file exists. Then you simply call the function in each method in your controller like this:
$this->doViews('main_content');
You should try using a Template library like this: https://github.com/philsturgeon/codeigniter-template
Then all you need to is put this in the controller (can be in __construct or within a method)
$this->template->set_partial('header', 'layouts/header');
$this->template->set_partial('footer', 'layouts/footer');
$this->template->set_partial('sidebar', 'layouts/sidebar');
Then to send data like you do with a view:
$this->template->build('create', $this->data);
you could create your main_view ... as a master page that already has a structure:
main_view.php
$this->load>-view('header');
<?php //get content here
?>
$this->load>-view('footer');
If you want to change something in the header or footer (through a statement) you can add content:
function __construct()
{
parent::__construct();
$data['footer'] = ($a == 'foo') ? 'footer one' : 'footer two';
$data_to_main = $this->load->view('template/footer', $data, TRUE);
$data_to_main = 'others';
$this->load>-view('main_view', $data_to_main);
}

How to display view without template?

I have view (frontend) in my own component (view.html.php):
class MevViewMev extends JView{
function display($tpl = null){
parent::display($tpl);
}
}
And template:
<?php defined('_JEXEC') or die('Restricted access'); ?>
<div>
ASFADSFDSF
</div>
How to display it without joomla template (head section, styles, etc). I want to call this part of jquery onclick method in the window.
To display the component only add "tmpl=component" parameter to url.
If need to display something besides component's view it can be customized - create "component.php" file in template's root folder and include in it whatever you need.
More templates can be done in the same way - create "some_template.php" in template's root folder and add "tmpl=some_template" parameter to url.
Start Edit
OK so the below works, but I found a better way. In your controller do ...
if (JRequest::getVar('format') != 'raw') {
$url = JURI::current() . '?' . $_SERVER['QUERY_STRING'] . '&format=raw';
header('Location: ' . $url);
// or, if you want Content-type of text/html just use ...
// redirect($url);
}
End Edit
You can set 'tmpl' to 'component', as suggested by Babur Usenakunov, in which case scripts and css may be loaded, like ...
JRequest::setVar('tmpl','component');
However if you want to create raw output you can add &format=raw or in your component make a view of type 'raw' ...
Unfortunately the only functional way I can find to make a viewType of raw render correctly is to call exit() after the view class calls parent::display() ...
In your controller.php ...
class com_whateverController() extends JController
{
function __construct()
{
// the following is not required if you call exit() in your view class (see below) ...
JRequest::setVar('format','raw');
JFactory::$document = null;
JFactory::getDocument();
// or
//JFactory::$document = JDocument::getInstance('raw');
parent::__construct();
}
function display()
{
$view = $this->getView('whatever', 'raw');
$view->display();
}
}
then in views/whatever/view.raw.php ...
class com_whateverViewWhatever extends JView
{
public function display($tpl = null)
{
parent::display();
exit; // <- if you dont have this then the output is captured in and output buffer and then lost in the rendering
}
}
I know this comes in very late, but for future readers, here's how I did it for my extension, without editing the template, or adding anything in the URL (since I have control over neither of those):
jimport('joomla.application.component.view');
use \Joomla\CMS\Factory;
// Comp stands for the Component's name and NoTmpl stands for the View's name.
class CompViewNoTmpl extends \Joomla\CMS\MVC\View\HtmlView {
// Force this view to be component-only
public function __construct() {
$app = Factory::getApplication();
$app->input->set('tmpl', 'component');
parent::__construct();
}

Resources