Fullcalendar not rendering inside Magento block - php

I have a custom block within Magento Community which rewrites the Orders Tab in Adminhtml and replaces it with a Fullcalendar(arshaw.com's one) which displays events for when products are to be shipped.
I have implemented a JSON feed which relies on my custom modules controller to populate and save the data. This works beautifully and I can see the products once I click on Month / Today / Prev / Next. However, this is not how it should work. It should render when the page loads, except all I see are the buttons.
I have tried referencing the tab in javascript which it is in eg.
jQuery('#diagram_tab_orders_content').tabs({
show: function(event, ui) {
jQuery('#dashCalendar').fullCalendar('render');
}
Where #dashCalendar is the id / class of my tag.
Except this does not render the calendar. It does nothing but change the CSS of diagram_tab_orders_content.
I've seen a similar topic on Stackoverflow where you must explicitly reference the tab where the calendar is in order for it to render properly. This is what I'm trying to achieve in order for the calendar to render when the document is ready.
Any suggestions on how to make this calendar render when the document is ready would be much appreciated.

So I've figured out the issue with the calendar and it pertains to the tabs within Magento. Referencing the tabs explicitly within Javascript causes issues with the rendering, thus I had to rewrite the Dashboard block.
Config.xml in my ModuleName/etc folder:
<global>
<!-- Blocks -->
<blocks>
<adminhtml>
<rewrite>
<dashboard>ModuleName_Block_Adminhtml_Calendar</dashboard>
</rewrite>
</adminhtml>
</blocks>
</global>
Then within my ModuleName/Block/Calendar.php file I set the template:
public function __construct()
{ //this creates the template block for the calendar
parent::__construct();
$this->setId('Calendar');
$this->setTemplate('moduleName/calendar/calendar.phtml');
}
Copy/Paste the fullcalendar's JSON Example page provided, set your events: tag to your .php file which generates / requests data from your database using JSON. Customise your Theme if you want using the provided CSS and you will see the calendar render with the events when you log into your Adminhtml. Below you will see 'Populate'. Its an action within my Controller which retrieves the data and echo's out a JSON feed to the Calendar.
events: {
url: "<? echo $this->getUrl('moduleName/adminhtml_calendar/populate') ?>"
},
Now the Calendar renders with events properly.

Related

Magento: adding link in head to every frontend page

I have a module that needs a canonical link injected into <head> on literally every page on frontend. Is there a way to do it? Currently, given my module doesn't need its own page on frontend, nor any controllers whatsoever, I have only set the helper in my config.xml. Now, I do have an xml in layout, but the problem is that I need to change canonical link attributes based on user input(in admin), so XML doesn't fit. Yes, I could indeed fopen said fronted layout xml file, then replace what I need, then write new content back to it, but I wanted to check first whether there's other way for achieving that.
You can hook in on the core_block_abstract_prepare_layout_before event and use the Head block's addLinkRel method to add the link tag.
In your config.xml you need to define an observer like so:
<events>
<core_block_abstract_prepare_layout_before>
<observers>
<your_module>
<class>Your_Module_Model_Observer</class>
<method>addCanonicalLink</method>
</your_module>
</observers>
</core_block_abstract_prepare_layout_before>
</events>
Create an observer class in the Model directory
<?php
class Your_Module_Model_Observer {
public function addCanonicalLink(Varien_Event_Observer $observer) {
$block = $observer->getData('block');
if ($block->getNameInLayout() === 'head') {
// this will add <link rel="canonical" href="http://your-url.com">
$block->addLinkRel('canonical', 'http://your-url.com');
// If you need more attributes on the link tag use addItem instead
// This will add <link rel="canonical" href="http://your-url" attr="Your Attribute">
// $block->addItem('link_rel', 'http://your-url', 'rel="canonical" attr="Your Attribute"')
}
}
}
Update:
Since the core head.phtml template files run echo $this->getChildHtml() (render all children) it is possible to insert tags by adding a core/text block as a child and add a text string to it (just like you already tried with xml). If addItem doesn't fit your needs, this is more flexible as you can insert any string this way. Replace thie $block->addLinkRel line with
$canonical = $block->getLayout()->createBlock('core/text')
->setText('<link rel="canonical" href="http://your-url.com">')
$block->append($canonical);

Understanding getChildHtml in Magento

From the following line in 2columns-right.phtml
<div class="col-main">
<?php echo $this->getChildHtml('global_messages') ?>
<?php echo $this->getChildHtml('content') ?>
</div>
I am not able to understand where the content in <?php echo $this->getChildHtml('content') ?> is coming from.
Which .phtml file is called to display the data by <?php echo $this->getChildHtml('content') ?>?
If we're discussing the frontend of the website, the particular line you've asked about....
<?php echo $this->getChildHtml('content') ?>
is added to the Magento layout XML in app/design/frontend/base/default/layout/page.xml. In Magento version 1.8, you'll find it defined in lines 92-94.
<block type="core/text_list" name="content" as="content" translate="label">
<label>Main Content Area</label>
</block>
By looking at the "type" attribute of this block tag, we can know what object class this section of the layout is. It comes from the "Core" module, and is of the block type Text List. The class name for this Mage_Core_Block_Text_List. (app/code/core/Mage/Core/Block/Text/List.php). Text Lists are simply block containers which purpose is to store additional child blocks inside them. You can add any number of child blocks to the text list and they will be rendered out either in the order they were added or the order they've been assigned.
So, to answer your question, there is no view script (.phtml file) that renders the contents of $this->getChildHtml('content'). The blocks which have been added to this block, may themselves have view scripts associated with them. To find out what view scripts those are, you'd have to find the layout XML which has added the block.
For example, if I had the following layout file added to the frontend of my website's theme:
<?xml version="1.0"?>
<layout>
<default>
<reference name="content">
<block type="core/template" name="my_view_script" template="hello/world.phtml" />
</reference>
</default>
</layout>
The code above, would add the block with an object class of Mage_Core_Block_Template to the block with the name 'content' (which happens to be the one you asked about). Magento will then look for the view script in the following locations, in this order:
app/design/frontend/PACKAGE_NAME/THEME_NAME/template/hello/world.phtml
app/design/frontend/PACKAGE_NAME/default/template/hello/world.phtml
app/design/frontend/base/default/template/hello/world.phtml
First one that is found, is the one it will use. If no view script is found Magento will log an error in var/logs/system.log (default log file setting) stating that the view script was not found. No output from the block will occur.
Note that depending on your settings in System -> Configuration -> (General) Design, there may be additional package/theme locations Magento will look in. There are also other scenarios such as if the "Custom Theme" is field is changed for individual CMS Pages, Catalog Categories, or Catalog Products, these individual model's view page may have an additional view script location (that will match the selected theme) that takes precedence over your site's default settings.
Magento will follow this same fallback logic when looking for translation files as well as layout XML files.
Please note, that it is perfectly acceptable to copy individual view scripts (avoid copying entire directories, copy over only view scripts you actually intend to modify) from app/design/frontend/base/default/template/ to your local theme, and customize them for the purposes of your website's theme. However, in order to have an upgrade compatible site, layout files should not be copied from base to your local theme. Doing so, does not follow upgrade compatible practices. Instead, XML Layout updates for your theme should be contained in app/design/frontend/PACKAGE_NAME/THEME_NAME/layout/local.xml. There is no layout instructions from app/design/frontend/base/default/layout/*, that cannot be removed/added-to/changed, what-have-you, with the proper XML instructions in local.xml.

Ajax in magento (load product view block)

What I want to achieve:
Clicking on a product link/image (at least in certain areas) to open a pop-up with the full product information (basically all the contents of the product view page).
What I did/tried so far:
created all the stuff outside the ajax php code (the module, links, templates, rewrites)
created the ajax controller (which can be accessed with a link similar to: http://test.com/index.php/ajaxproductview/ajax/index/id/2 ).
to follow various tutorials ( like this or this ) - that helped me get this far. But I don't want to load my custom block, I want the default product view block(s).
tried to add some code in the indexAction(). It gets there, but the code fails. I don't get any errors/notices/reports, just what it seems like an infinite loop that kills my processor.
$body = $this
->getLayout()
->createBlock('product.info') // taken from catalog.xml
->toHtml();
$this->getResponse()->setBody($body);
All the other pages work fine, and it's a fresh magento with only magneto and my module installed and activated.
My AJAX function simply gets this HTML response, puts it into a div, and opens a pop-up.
My question(s) is(are) - how can I set the product id, so the block knows what product to load, and how can I load this block correctly. I also tried something similar to this:
Thank you.
PS: I also tried this:
$layout = $this->getLayout();
$update = $layout->getUpdate();
$update->load('catalog_product_view');
$layout->generateXml();
$layout->generateBlocks();
$output = $layout->getOutput(); // $output is an empty string
The Product controller uses a helper to set the active product. You should be able to do the same in your controller!
Try this before you do your layouting:
$productId = (int) $this->getRequest()->getParam('id');
Mage::helper('catalog/product')->initProduct($productId, $this);
Another thing to be aware of:
If you add a block like the product.info block. It needs additional child blocks if it calls them in its template file.
It would be easiest to use a custom layout xml file. You can then add a specific layout for your action handle (your action handle consists of your routers node in your module's etc/config.xml file under <frontend><routers>, e.g. <Yourmodule> node, make sure to lowercase it! And then with underscores add the controller name and action name, in your case index_index) like this:
<yourmodule_index_index>
<remove name="right"/>
<remove name="left"/>
<block type="catalog/product_view" name="root" output="toHtml" template="catalog/product/view.phtml">
<!-- Add all the child blocks you need -->
</block>
</yourmodule_index_index>
This makes the view.phtml the root block which renders itself using its toHtml method.
Therefore, in your controller action, all you need is my two lines above and then:
$this->loadLayout();
$this->renderLayout();

Magento - Add custom modules to Google sitemap

I have custom modules (that I bought or developed) that have frontend pages in my store.
How can I include these pages in the Google sitemap Magento generates?
The function that generates the sitemap is: Mage_Sitemap_Model_Sitemap::generateXml()
which does the following:
open file and write xml header
get the category collection and write it to sitemap file
get the products collection and write it to sitemap file
get the CMS collection and write it to sitemap file
close the sitemap xml file
No event is dispatched before closing the xml file... in this case you can extend this Mage_Sitemap_Model_Sitemap and override the generateXml() function adding your own custom URLs (if these urls are not in any of the above collections: category, product, cms page)
Another approach to your issue is using multiple sitemap files and a sitemap index file (Google Supports this: http://googlewebmastercentral.blogspot.co.uk/2006/10/multiple-sitemaps-in-same-directory.html). In this case, you can have a separate module to generate the 2nd xml sitemap file.
Magento did add the events sitemap_products_generating_before and sitemap_categories_generating_before in later versions (I don't know when, my version is 1.9.2). So in case you stumple upon this thread like me, looking for the best way to add custom modules' pages to the Google Sitemap, this is how simple it is with these events:
In my case I have a custom module that creates dynamic "News" pages, so I add an event listener to the <global> tag in my module's config.xml. I chose to go with the product sitemap event*:
<events>
<sitemap_products_generating_before>
<observers>
<{your_unique_event_observer_name}>
<class>{Brand}_{Module}_Model_Observer</class>
<method>addPagesToSitemap</method>
</{your_unique_event_observer_name}>
</observers>
</sitemap_products_generating_before>
</events>
And then, in my module's Observer, I let the method addPagesToSitemap add extra items to the product collection (or category collecton, if you went with the category sitemap event):
class {Brand}_{Module}_Model_Observer
{
function addPagesToSitemap(Varien_Event_Observer $observer){
$sitemapItems = $observer->getEvent()->getCollection()->getItems();
// Get your module's page collection including their urls
// Adjust the following lines to your needs
$collection = Mage::getModel('{brand}_{module}/pages')->getCollection()
->addFieldToSelect(array('page_id','url'))
->addFieldToFilter('display', 1);
// My module stores the page path separately,
// you might don't need this:
$modulePagePath = Mage::helper('{my-modules-helper}')->getNewsPath();
foreach($collection as $_item){
$varienObject = new Varien_Object();
// We don't want to override
// any existing product/category items
$uniqueId = '{module}'.$_item->getPageId();
$varienObject->setId($uniqueId);
// You might want to adjust this if your item
// stores the complete url. Don't add the base url tho,
// Mage_Sitemap_Model_Sitemap::generateXml adds it
$varienObject->setUrl($modulePagePath . DS . $_item->getUrl());
$sitemapItems[$uniqueId] = $varienObject;
}
$observer->getEvent()->getCollection()->setItems($sitemapItems);
return $this;
}
}
That's it. You can test it by manually generating your sitemap under Catalog > Google Sitemap.
*For some reasons Magento did not add an event "sitemap_pages_generating_before", so you have to either choose the products' or category's event to go with. For both events Magento takes the respective changefreq- and priority-value set for category & product pages in your Magento configuration. So just choose the event which values fit better.

What are the possibilities to add generated html from module in magento?

I am trying to debug external module in Magento. In that, when i logged in admin end, I have got pop up with some message and also got one notification message.Installed module generate the code for script to alert the popup message,div to display the notification. This HTML is generated and appended in DASHBOARD page which is having body class as " adminhtml-dashboard-index"
I guess there might be some way to push the generated code with dashboard page.
What are the possible ways to add external module notification or some html or generated js script with core module like DASHBOARD?
Hope you understand my question...
Thanks in advance
Here's one way to drop a block in there. Observe the adminhtml_block_html_before event:
<events>
<adminhtml_block_html_before>
<observers>
<super_adminhtml_block_html_before>
<class>super/observer</class>
<method>beforeAdminHtml</method>
</super_adminhtml_block_html_before>
</observers>
</adminhtml_block_html_before>
</events>
Then, create a new block and append it to the notifications block.
public function beforeAdminHtml($observer)
{
$block = $observer->getEvent()->getBlock();
if ($block->getNameInLayout() == 'root') {
$extendBlock = $this->_createMyNoticeBlock();
if ($extendBlock) {
$block->getChild('notifications')->append($extendBlock);
}
}
}
I used this to insert my own HTML block where the notifications usually show within the header - shows not only on the dashboard but on all the admin pages.

Categories