Jump to content

Stuck with a module to create a simple back office page


prestafan123

Recommended Posts

I am trying to add some functionality to my shop and have spent the past two days trying to come to grasp with how smarty actually works within prestashop or rather in general.

 

I have so far made a module that can install, on install it creates a tab on the left menu, I can click on the tab and it will load the controller but this is where i get stuck... I can't figure out how to display custom content within that state.

 

What i would like is very simple, just a paragraph of text and a button. When clicking the button i will do a few things and record a few things then show the results as a simple report.

 

So for starters... I'd like to create the page with the paragraph and button.

 

So i have created a folder in the module diretory called priceupdate and inside of this there is:

 

/priceupdate.php
 

<?php
if (!defined('_PS_VERSION_'))
exit;

class PriceUpdate extends Module
{
    public function __construct()
    {
        $this->name = 'priceupdate';
        $this->tab = 'quick_bulk_update';
        $this->version = '0.8';
        $this->author = 'Me';
        $this->need_instance = 0;
        $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
        $this->bootstrap = true;
        
        parent::__construct();
        
        $this->displayName = $this->l('Pricing Update');
        $this->description = $this->l('Adds functionality relating to maintaining product my prices.');
        
        $this->confirmUninstall = $this->l('Are you sure you would like to uninstall?');
    }
    
    public function install()
    {
        if (!parent::install()
        || !$this->installModuleTab('AdminPricingUpdate', array(1=>'Pricing Update'), 0))
        return false;
        return true;
    }
    
    public function uninstall()
    {
        if (!parent::uninstall()
        || !$this->uninstallModuleTab('AdminPricingUpdate', array(1=>'Pricing Update'), 0))
        return false;
        return true;
    }
    
    private function installModuleTab($tabClass, $tabName, $idTabParent)
    {
        $tab = new Tab();
        $tab->name = $tabName;
        $tab->class_name = $tabClass;
        $tab->module = $this->name;
        $tab->id_parent = $idTabParent;    
        if(!$tab->save())
        return false;
        return true;    
    }
    
    private function uninstallModuleTab($tabClass)
    {
    $idTab = Tab::getIdFromClassName($tabClass);
    if($idTab != 0)
    {
        $tab = new Tab($idTab);
        $tab->delete();
        return true;
    }
        return false;
    }
}
?>

And:

 

/controllers/admin/AdminPricingUpdateController.php
 

<?php
class AdminPricingUpdateController extends AdminController
{

public function __construct()
{
$this->lang = (!isset($this->context->cookie) || !is_object($this->context->cookie)) ? intval(Configuration::get('PS_LANG_DEFAULT')) : intval($this->context->cookie->id_lang);
parent::__construct();
}

public function display(){
parent::display();
}

public function renderList() {
return $this->context->smarty->fetch(dirname(__FILE__).'/content.tpl');
}

}
?>

This works however where I am stuck relates to the content.tpl part. What goes inside of this the content.tpl file in order to get it to make a blank page of content within the content area of the admin section?
 
I've looked through the manual and spent countless hours on forums looking though questions, tried to figure it out by breaking down other modules but i've found it too complex to really understand what is what.
 
If anyone could help me to understand this or point me to a source of info on this specific subject then it would be greatly appreciated, thanks!

Edited by prestafan123 (see edit history)
Link to comment
Share on other sites

if your output is very basic you could simply use:

public function renderView() {
      $html = '<p>';
      $html .= $this->l('This is the translatable text inside the paragraph');
      $html .= '</p>';
      return $html;
}

without the tpl

 

Thanks for the reply! I really apprecaite it.

 

I gave it a try and ended up with this for the controller:

 

/controllers/admin/AdminPricingUpdateController.php

<?php
class AdminPricingUpdateController extends AdminController
{
    public function renderView() {
      $html = '<p>';
      $html .= $this->l('This is the translatable text inside the paragraph');
      $html .= '</p>';
      return $html;
    }
}
?>

When i click on the link that was created by the module now, I get a a new page in the content area of the back office (exactly what i wanted to populate with a simple feature). This being said, It is just a blank page and displays no content.

 

I have given this a try too:

class AdminPricingUpdateController extends AdminController
{
    public $bootstrap = true ;
    
    public function initContent()    
    {
        parent::initContent();   
        $smarty = $this->context->smarty;

        $smarty->assign('test', 'test1');
    }
}

Which should as I understand it load content from from a content.tpl file containing:

zzz{$test}zzz

Then display zzz{Test1}zzz in the content area. I don't get any content there either? Where should the .tpl file be located within the modules folder in order for it to load? Must i specifiy it somehow?

 

Either way, I appreciate the input and would apprecaite equally any further that is provided!

 

As a note to the PrestaShop team... Please guys, it would really help worlds if you explained how to do this within the manual with a simple example. You have one for displaying front end content but it is more complex and deals with the front end specifically! It's really hard to grasp for a beginner :(

Edited by prestafan123 (see edit history)
Link to comment
Share on other sites

hello, about the tpl for the packoffice tab you can see how other modules do it, I never checked, for example I see PayPal module have backoffice tpl located in:

 

modules/paypal/views/templates/back

modules/paypal/views/templates/admin

 

the module tab controller is always like this:

class MyModuleTabController extends ModuleAdminController
{
	public $html;

	public function __construct()
	{
		$this->html = '';
		$this->display = 'view';
		$this->meta_title = $this->l('metatitle');
		$this->toolbar_title = $this->l('tollbartitle');
		
		parent::__construct();
	}

	public function initContent()
	{
		$this->postProcess();
		$this->context->controller->addJS(_MODULE_DIR_.'modulename/js/script.js');
		$this->context->controller->addCSS(_MODULE_DIR_.'modulename/css/style.css');
		$this->show_toolbar = true;
		$this->display = 'view';
		$this->meta_title = $this->l('META TITLE');
		parent::initContent();	
	}
	
	public function initToolBarTitle()
	{
		$this->toolbar_title = $this->l('TOOLBAR TITLE??');
	}
	
	public function initToolBar()
	{
		return true;
	}
	
	public function renderView() {
                $this->html .= '<form id="moduleform">';
		$this->html .= '<div class="moduleHTML">text text text</div>';
                $this->html .= '</form>';
		
		return $this->html;
	}
        
        public function postProcess() {
           //something here to handle your contoller requests 
        }
}

this will work but wont use any tpl

Edited by misthero (see edit history)
  • Like 2
Link to comment
Share on other sites

Thank you so much! that really helps like you would not believe... It was 3 days now and I finally understand how things works thanks to you!!! The question is solved but I have two more small questions though.

 

postProcess()

 

From my understanding, if there is a submit button in the form then this is the result, so anything that happens after you click the button goes in there.

 

I am taking it that this deals with the event of a button being clicked... But what happens if there is more than one button?

 

Also, once i click the button the form is processed, I will in my design have some results to show. What would the correct process be in passing the results off to another view so i could have a report?

 

So inside postProcess() I have some results, how do I show the results?

 

addCSS()

 

Also, if I want to override a style that is in use within the back office i,e, A style that applies to my new tab that gives it an icon (there is no icon, i need to assign :before content). How do I modify this during the install? Do i just need a .css file with the right name in the right directory within the modules folder? If so where and what name?

 

I can apply the style within the modules css file (the one that I have told it to load using addCSS however this does only gives the icon if the tab is in use / I am viewing the page. When i go to another tab, there is no icon again.

 

It would basically be an override of admin-theme.css but not manually.

 

Again, thank you so much this was REALLY helpful!

Edited by prestafan123 (see edit history)
Link to comment
Share on other sites

glad to help,

 

sadly i don't know if there is a specific method for the tab logo, the addCss() in this case will add css only when you are in the tab, if you want a css that is applied always in backoffice you should add it with an hookBackofficeHeader in the main module file

 

postProcess() is just an example, is not required, it is called before anything else in the example just because it is inside initContent() but you could use it inside renderView() instead or skip it at all, it really depends on what you need to do. Usually it will make your code prettier and more readable splitting in functions.

 

for example if you want to change a product name you could have a form with 2 input fields, named product_id and product_name

<input type="text" name="product_id"/>
<input type="text" name="product_name"/>

inside postProcess you can than do this:

public function postProcess() {
    if (Tools:getValue('product_id') && Tools:getValue('product_name') {
       $product = new Product(Tools:getValue('product_id'));
       $product->name = Tools:getValue('product_name');
       $product->update();
    }
}

this will not display anything just handle the product and change his name

 

anyway you could add a message with $this->_html

public function postProcess() {
    if (Tools:getValue('product_id') && Tools:getValue('product_name') {
       $product = new Product(Tools:getValue('product_id'));
       $product->name = Tools:getValue('product_name');
       if ($product->update())
           $this->_html .= $this->l('Product updated!!');
    }
}

if you think the orignal question is solved please change the title prepending it with [sOLVED], so others can find the solution ;)

Edited by misthero (see edit history)
  • Like 2
Link to comment
Share on other sites

Thanks so much, I am over the moon happy; it works nicely! :)

 

One last question:

 

hookBackofficeHeader in the main module file

 

Would you be able to provide a simple code example of this? Hooks really confuse me a lot, I tried this in the module controller:

public function install()
    {
        if (!parent::install()
            || !$this->installModuleTab('AdminPricingUpdate', array(1=>'Pricing Update'), 0)
            || !$this->registerHook('displayBackOfficeHome') )
            return false;
        return true;
    }

And With:

public function hookDisplayBackOfficeHome($params)
    {
        $this->addCSS(_PS_MODULE_DIR_.'pricingupdate/main.css');
    }

But it seems that i am mis-understanding things!

Link to comment
Share on other sites

I really cannot say thank you enough! You helped me SO SO SO SO SO much, THANK YOU!!!

 

Everything is working perfectly and better than i had ever hoped! Yay!!

 

Taken me almost a week but i kind of understand Prestashop module development now. I don't want to make a commercial module, just something that will make my life easy so that I can update my pricing in bulk (i have all that logic and everything working) and now! I can actually do that... Sooooo Happy!!!!

Link to comment
Share on other sites

  • 2 years later...

I have created one module and I'm  trying to add new page when user click on hyperlink new page is displayed.

how to create new page into that module .

<a id="desc-tag-new" class="list-toolbar-btn" href="'.#.'"> <- here i want to pass url of that page.
<span title="" data-toggle="tooltip" class="label-tooltip" data-original-title="Add new" data-html="true" data-placement="left">
<i class="process-icon-new"></i>
</span>
</a>
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...