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.
Related
If I create custom field in Joomla, it's will show in homepage (featured article) and blog category menu.
I want custom fields to only show in a single article. It should be hidden in the homepage (featured articles) and blog category menu.
Where can I setting it or modify in PHP code?
The files you need to override are at \components\com_content\views\featured\tmpl\default_item.php and \components\com_content\views\category\tmpl\blog_item.php
Important : core files should be overridden in your template, and the core code left unchanged.
The fields themselves are generated by the lines
<?php // Content is generated by content plugin event "onContentBeforeDisplay" ?>
<?php echo $this->item->event->beforeDisplayContent; ?>
Note that removing these lines will also stop any other plugin which uses this area from working. As far as I can tell, the only other thing to use it is the voting system. If you need that, then you may need to write a bespoke plugin or just hide the area with CSS.
You can create the override of Layout com_fileds - field.
(copy the file render.php from components/com_fields/layouts/field/ to templatename/html/layouts/com_fields/field/)
Add two new variables and one more condition on the if condiction
defined('_JEXEC') or die;
$app = JFactory::getApplication();
$view = $app->input->getCmd('view', '');
if (!key_exists('field', $displayData) || $view != 'article')
{
return;
}
we have a subdomain multisite setup. We would like to have products listed in the both the main site (containing many brands/manufacturers) and a separate subsite that caters to that brand specifically.
A visitor to the main site can perform a product search or browse the categories to locate any products. If they click on a product to view it’s information/order, they will be directed to the subsite to have the product display there
Ordering the item will then take them through the cart process of the subsite with unique shipping extensions etc to that site.
Is this possible? Surely if the products are listed in the root site category but display in both, we should be able to tweak the scripta so that is directs to the subsite to order...
We’re not expecting this to be possible without customization, but not sure how to go about it.
You want to redirect to the brand site exactly when the product page on the main site is accessed. So what you can do is write an observer for the event controller_action_postdispatch_catalog_product_view, check if the current website is the main website and if the product is available on another website. If yes, redirect to this website. I choose postdispatch over predispatch because at this point the product is already loaded and we can easily retrieve the website information.
To do so, create a new module (I spare the basics here), configure the observer:
config.xml
<frontend>
<events>
<controller_action_postdispatch_catalog_product_view>
<observers>
<your_module>
<class>your_module/observer</class>
<method>redirectToBrandSite</method>
</your_module>
</observers>
</controller_action_postdispatch_catalog_product_view>
</events>
</frontend>
and implement the logic from above:
Observer.php
class Your_Module_Model_Observer
{
const MAIN_WEBSITE_ID = 1;
public function redirectToBrandSite(Varien_Event_Observer $observer)
{
if (Mage::app()->getWebsite()->getCode() != self::MAIN_WEBSITE_ID) {
return;
}
$product = Mage::registry('current_product');
if (!$product instanceof Mage_Catalog_Model_Product) {
return;
}
foreach ($product->getWebsiteIds() as $websiteId) {
if ($websiteId != self::MAIN_WEBSITE_ID) {
$redirectUrl = $product->setStoreId(
Mage::app()->getWebsite($websiteId)->getDefaultStore()->getId()
)->getProductUrl();
$observer->getControllerAction()->getResponse()->setRedirect($redirectUrl);
return;
}
}
}
You have to set the MAIN_WEBSITE_ID constant to the id of your main website (not the code). You can look that up in the core_website database.
You can create multiple store to achieve main website and sub site. My be you need to create URL redirections to redirect products to subsite.
I have an installed addon for magento called Fishpig. It essentially runs wordpress through magento allowing both to be used on the main website. The WP install is being used for a blog, and i've the whole initial theme set up for it by altering the magento files as required. What i'm looking for though is a way to change the theme if i look under a certain category related to the representative for the site.
Is there a way to set a different template if i were to choose the category? Will i need to add if statements to the category WP layout file?
If you want to change the whole theme based on the current WordPress category (or any conditions), you would need to listen to for an event and then change the theme programmtically. The most general event that would work would be 'controller_action_predispatch' however if you wanted to only change the theme for WordPress category pages, you would be better suited to use 'controller_action_predispatch_wordpress_post_category_view'.
Attach an event observer method to the event of your choosing and then use the following code:
$_category = Mage::registry('wordpress_category');
if (!$_category) {
return $this;
}
$_categoryId = (int)$_category->getId();
if ($_categoryId === 1) {
Mage::getDesign()
->setPackageName('default')
->setTheme('default');
}
else if ($_categoryId === 2) {
Mage::getDesign()
->setPackageName('default')
->setTheme('default');
}
return $this;
You would need to modify to code to set the correct package/theme (the code below enables the default package and default theme) to match the package/theme you want to set.
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();
I have the following problem:
I use taxonomys (tx) as tags. They can be added when the node is created. So I don't know how many tx I have or what ID they have.
The path of the tx is like the following:
/foo/element1
/foo/element2
/foo/element3
...
The secound element is the tx.
Now I want to use a view (page) to handle the tx-path:
/foo/%
The problem is, when I open a path like the one on top I see the theme of the node-taxonomy.tpl.php but not the style I set in the view.
Whenever I open a path in the form (/foo/not-a-tx) I can see the output of the view.
Could someone give me a hint how to get out the view output but not the tx-output?
Thanks
Sebastian
I solved the problem with this way:
I use a view block (not a page)
I added a new output area in my ,info file
I use this way to show only the vocab
I show the block in the new area online bei foo/*
It works Okay for me.
Thx to every one.
Do you want to get rid of the taxonomy pages completely?
If so, you can use a hook_menu_alter() and unset the taxonomy page.
EX.
hook_menu_alter(&$items) {
unset($items['taxonomy/term/%taxonomy_term']);
}
You'd have to look at the $items array to pinpoint the name of the registered menu path, but I think this is it.
This will remove the taxonomy page for all vocabularies however.
Actually you need to make a view to override the internal drupal path of the taxonomy term page: taxonomy/term/% (where % is the taxonomy id) and not the aliased path, which in your case is foo/%
[Optional but saves work: There is already an example view that is bundled with Drupal that implements the taxonomy view. Go to Views > List and you will see the the view is greyed out and it is called
Default Node view: taxonomy_term (default)
All you need to do is enable it and modify it to your needs]
Don't worry about the aliases. You can define your URL pattern at /admin/build/path/pathauto (make sure pathauto module is enabled. You can download it at http://drupal.org/project/pathauto ). In your case the pattern would be foo/[cat] where [cat] is a token for category. Make sure you enter this pattern under Taxonomy Term paths in the pathauto automated alias settings.