I'm trying to figure out the best course of action to change URL keys in the store to be name-sku.html
Currently MAGMI seems to be dictating the url key, which is fine. Some of our products are not imported through MAGMI, so I think I'd probably have to also use the updateurl event to change the url on save -- I found this here for that -- https://magento.stackexchange.com/questions/24869/manufacturer-in-product-url-key
The question is, how is it best to do this within MAGMI? I'm importing about 300,000 products currently. The URL also needs to change, as it currently just uses the default settings.
I've looked into the wiki here -- http://wiki.magmi.org/index.php?title=Value_Replacer -- I guess the following code could work for the way it is currently working -- but what do I actually type into the value replacer box?
{{ Slugger::slug({item.name}) }}
Does anyone know how to add the sku to this as well? Would I just do something like....
{{ Slugger::slug({item.name} ."-". {item.sku}) }}
Also, does anyone know if this automatically adds the dashes and the .html?
Any guidance would be extremely appreciated.
EDIT:
I have successfully tested this as working in my test environment, but it is not working as expected in my production environment. I'll go over what happens, and what I did.
1) I purged the core_url_rewrite table
2) I deleted all cache
3) I set up MAGMI (updated it to the most current version as well, and triple checked all my settings)
4) MAGMI went through fine, and the url key on about 5 products that I checked for were how I would expect
5) During the catalog url rewrites reindex, all url keys disappeared.
6) After the reindex was done, they were now in the default magento format (using just the name, and not the sku)
Any ideas?
The only difference between production and development that I can think of at the moment that may have anything to do with this is the fact that I did create a module based on the linked manufacturer-in-product-url-key question on production. Now that I think of it, maybe that's the main difference that I need to address..... I didn't think reindexing would have anything to do with that, but maybe I'm wrong.
Anyway, if anyone has any insight, I would still appreciate it. I have a feeling maybe MAGMI should also be rewriting the url_path?? I think I read something about that somewhere.
Ok, I figured this out. I think this is the best approach.
I was mistaken in my question. I'm actually looking to add the mpn, not the sku. Either way, that doesn't change the process.
So, the best thing to do is to use the Value Replacer in MAGMI, and to create a custom module that updates the url on the Magento catalog_product_save_before event.
Here's exactly what I did.....
MAGMI settings (Value Replacer)
Replaced attributes: url_key
New value for url_key: {{ Slugger::slug({item.name}.' '.{item.mpn}) }}
URLKeyChange (Magento Module)
app/code/local/My/URLKeyChange/etc/config.xml
<config>
<global>
<models>
<LeathornURLRewrite>
<class>Leathorn_URLKeyChange_Model</class>
</LeathornURLRewrite>
</models>
<events>
<catalog_product_save_before>
<observers>
<LeathornURLRewrite>
<type>singleton</type>
<class>LeathornURLRewrite/observer</class>
<method>updateurl</method>
</LeathornURLRewrite>
</observers>
</catalog_product_save_before>
</events>
</global>
</config>
app/code/local/My/URLKeyChange/Model/Observer.php
class My_URLKeyChange_Model_Observer {
public function updateurl($observer){
Mage::log('My log entry', null, 'mylogfile.log');
if($observer->getEvent()->getProduct()){
$Product=$observer->getEvent()->getProduct();
$Url='';
if(!is_null($Product->getData('name'))):
$Url=$Url.$Product->getData('name');
endif;
if(!is_null($Product->getData('mpn'))):
$Url=$Url.$Product->getData('mpn').'-';
endif;
//Mage::log('My log entry'.$Url, null, 'mylogfile.log');
$Product->setData('url_key',$Url);
}
}
}
app/etc/modules/My_URLKeyChange.xml
<config>
<modules>
<My_URLKeyChange>
<!-- Whether our module is active: true or false -->
<active>true</active>
<!-- Which code pool to use: core, community or local -->
<codePool>local</codePool>
</My_URLKeyChange>
</modules>
</config>
URL key will always be just dash separated strings. Don't worry, magento will add .html in it dynamically. You can see in magnento backend in any product configuration page, url key is without html.
Also magento will add dash in url key, Replace your "-" by space " ". Otherwise it will take last word of name and SKU as one word. :)
Related
How to sell a coupon code in magento.
The coupon code that can be gift to a friend, so that he can buy products with that code?
Log in to Magento Admin.
Click on Promotions –> Shopping Cart Price Rule.
On Right side click on Add new rule.
Fill in the fields be sure to give the rule a Name and Description and decide whether or not you are choosing ALL Customer groups or not.
In the General Information page in the coupon menu, select the Specific Coupon option.
Enter a code in the coupon code field (can be letters or numbers).
In the Uses Per Coupon field, specify the number of times a customer can use this coupon code if you would like to provide a limit. If not, leave blank.
In the Uses Per Customer field, specify the number of times a customer can use this promotion if you would like to provide a limit. If not, leave blank.
In the From/To Date menu, select a time frame for your coupon if you would like to provide one. If not, leave blank.
IDEA:
create coupon rule with auto generated coupons
create specific controller which will generate coupon and display it to customer
create downloadable product with link to our controller
NOTE
THIS IS MY FIRST INITIAL IDEA AND I'M NOT SURE IF IT IS PROPER SOLUTION.
I've never dealt with downloadable products before.
FIRST STEP CREATE COUPONS
When adding new rule to Shopping Cart Price Rules fill all required fields, remember to select appropriate customer groups (include NOT LOGGED IN if coupon should be available for guest customers).
Then, in Coupon select Specific Coupon, and select Use Auto Generation in checkbox below. Uses per Coupon set to 1. You can also set time limit if you want to.
Then save.
After saving new tab will appear on the left: Manage Coupon Codes.
There you can generate many coupon codes by setting qty (amount of coupons to generate), code length, code format (letters and digits, letters, only digits), code prefix and/or suffix, and if to include dash every x characters.
Remember code length applies only to generated part without dashes, prefix or suffix.
You don't need to generate anything yet, I'm just explaining some properties which I will refer to later on.
SECOND STEP PREPARE MODULE
Create path app/code/local/Example/Coupon, and two directories there etc and controllers.
In etc create config.xml
<?xml version="1.0"?>
<config>
<modules>
<Example_Coupon>
<version>0.1</version>
</Example_Coupon>
</modules>
<global>
</global>
<frontend>
<routers>
<example_coupon>
<use>standard</use>
<args>
<module>Example_Coupon</module>
<frontName>mycoupon</frontName>
</args>
</example_coupon>
</routers>
</frontend>
</config>
Then IndexController.php in controllers:
<?php
class Example_Coupon_IndexController extends Mage_Core_Controller_Front_Action {
const RULE_ID = 4;
public function indexAction() {
$rule = Mage::getModel('salesrule/rule')->load(self::RULE_ID);
$generator = Mage::getModel('salesrule/coupon_massgenerator');
$generator->setFormat(Mage_SalesRule_Helper_Coupon::COUPON_FORMAT_ALPHANUMERIC);
$generator->setDash(false);
$generator->setLength(6);
$generator->setPrefix('EX');
$rule->setCouponCodeGenerator($generator);
$rule->setCouponType(Mage_SalesRule_Model_Rule::COUPON_TYPE_AUTO);
$coupon = $rule->acquireCoupon();
$code = $coupon->getCode();
$coupon->setType(Mage_SalesRule_Helper_Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)->save();
die($code);
}
}
Here actual coupon is being generated and saved (upon requesting our custom url). Note that here all properties of code are defined (described above). You should edit this to suit your needs.
You can access this by visiting http://www.yourstore.com/mycoupon/index
Finally you need to enable module in etc/app/modules
create Example_Coupon.xml
<?xml version="1.0"?>
<config>
<modules>
<Example_Coupon>
<active>true</active>
<codePool>local</codePool>
</Example_Coupon>
</modules>
</config>
THIRD STEP ADD DOWNLOADABLE PRODUCT
I'm not going to cover all the details here, there is a good tutorial: https://www.hostknox.com/tutorials/magento/downloadable-products
What you finally need to do is to provide previously generated url as an downloadable link: http://www.yourstore.com/mycoupon/index
ISSUES
It works, but:
There is no validation whatsoever if customer have all rights to download this coupon or not. I'm not sure, maybe magento covers this or maybe not. There is an option to disable sharing in magento, so I would expect magento to hide this final url from customer.
You would probably need to expand my example module, because there should be downloadable file at the end - most likely some kind of PDF. Not simply echoing new generated coupon.
This file should be stored somewhere on disk, and served again upon request from same customer and same order.
I have had a request to change the url of a module.
For example let's say the url is www.example.com/world
I need the url to be www.example.com/hello/world
I know that within the modules config xml you can change the node to whatever you like (provided it's unique) but does not allow prepend /hello/
<frontend>
<routers>
<anexample>
<use>standard</use>
<args>
<module>An_Example</module>
<frontName>hello/world</frontName>
</args>
</anexample>
</routers>
</frontend>
Does anyone have any idea how this can be done ? Some example code or even a point in the right direction would be appreciated!
Sorry if this isn't detailed enough, i'll be happy to post more of my code if required.
Thanks in advance.
You can add rewrites into Magento's URL Rewrite Manager. Haven't tested following code. But hope it helps.
Mage::getModel('core/url_rewrite')
->setIsSystem(0)
->setStoreId($storeId)
->setOptions('RP')
->setIdPath('index.php?cat=c' . $categoryId . '_' . $this->strip($data['name']) . '.html')
->setTargetPath($categoryModel->getUrlPath() . '.html')// Put the actual path
->setRequestPath('index.php?cat=c' . $categoryId . '_' . $this->strip($data['name']) . '.html') // put the path you want to display
->save();
here i can give you idea to reach your solution it will sure help you
<?xml version="1.0"?>
<config>
<global>
<rewrite>
<some_unique_name_to_identify_this_rewrite>
<from><![CDATA[#^/from_this/#]]></from>
<to>/to_this/</to>
</some_unique_name_to_identify_this_rewrite>
</rewrite>
</global>
</config>
And if you want to do url rewrite with Admin functionality you can go throw this link
Also what you want to achieve could be done with Custom Url Rewrite. For example:
request path: hello/world
target path: 'world'
In this way you're making a destination of system rewrite yours start point.
hope this will sure help you
This was pretty simple in the end. Instead of going to the hassle of creating a rewrite for it i just changed my frontname to 'hello' then created a controller called 'worldController'
Then in my indexController i just put a redirect to */world
Please see the following article by Allan Storm about the Magento rewrite
http://alanstorm.com/magento_dispatch_rewrites_intro
Access custom Module controller path as custom HTML Url Link
Say http://domain.com/index.php/customwallpaper/index/create/
will be rewrited to
http://domain.com/index.php/fotomural-personalizado.html
Insert below data in core_url_rewrite table for url rewrite
Mage::getModel('core/url_rewrite')
->setStoreId(1)
->setIdPath('customwallpaper')
->setRequestPath('fotomural-personalizado.html')
->setTargetPath('customwallpaper/index/create') // Put the actual Controller path
->setIsSystem(1)
->save();
-OR-
Run below sql query
INSERT INTO `core_url_rewrite`
(`url_rewrite_id`, `store_id`, `id_path`, `request_path`, `target_path`, `is_system`, `options`, `description`, `category_id`, `product_id`)
VALUES ('7', '1', 'customwallpaper', 'fotomural-personalizado.html', 'customwallpaper/index/create', '1', NULL, NULL, NULL, NULL);
I've been looking for a while at other threads, several have been close to what I need but not quite.
When a guest or customer sign up for our newsletter the field change_status_at populates with a timestamp.
However, if the guest or customer unsubscribe, we would like the the change_status_at field to pickup the current timestamp.
This is important to use because we do not use the newsletter "feature" of Magento 1.7.0.2 CE. Rather we export the newletter_subscriber list to a company to send an email.
Thank you,
Dan
I just ran into this too. A customer wanted to know the date when a subscribe/unsubscribe action occurred. Looking around the internets I've found a few others who have run into this and some claim that it used to work in very old version of Magento.
I think what happened is that the field definition for change_status_at used to be setup to auto update as a default timestamp (i.e. ON UPDATE CURRENT_TIMESTAMP), but that was lost in some update. So there's no Magento code that writes to the field, because MySql is supposed to magically maintain it.
You could try updating the table definition to add the ON UPDATE CURRENT_TIMESTAMP back in (but I'm not in favor changing default model tables) or adding another field to be the default timestamp field.
Or a better solution would be to create a module with an observer to just add the date in when the subscription changes. Here's that might look like (warning - this code is just an example, there may be some syntax errors due to expunging my module's info) -
app/code/local/Myco/MyMod/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Myco_MyMod>
<version>1.0.0</version>
</Myco_MyMod>>
</modules>
<global>
<models>
<myco>
<class>Myco_MyMod_Model</class>
</myco>
</models>
<events>
<newsletter_subscriber_save_before>
<observers>
<mycomymod_observer_subscriber>
<type>singleton</type>
<class>Myco_MyMod_Model_Observer</class>
<method>setUpdateDate</method>
</mycomymod_observer_subscriber>
</observers>
</newsletter_subscriber_save_before>
</events>
</global>
</config>
===========
in app/code/local/Myco/MyMod/Modules/Observer.php
<?php
class Myco_MyMod_Model_Observer
{
public function setUpdateDate(Varien_Event_Observer $observer) {
$subscriber = $observer->getSubscriber();
$subscriber['change_status_at'] = (date("Y-m-d H:i:s", time()));
}
}
I'm developing a custom module for my Magento installation (version 1.6.2.0). I registered a translation file for the module in the config.xml and started to add German translations. The module adds some new behavior to the Magento back end.
While doing the translation I noticed a strange behavior of Magento. Certain words don't get translated by Magento although a translation is provided in the module's csv file.
When I change the key to a different value, the translation works as expected, so Magento seems to see and read the cvs file.
At the moment I notice this behavior for the keys "City" and "Store".
Content of the csv file:
"City","Stadt"
"City1","Stadt"
I use the following line to translate the strings.
Mage::helper('mymodule')->__('City') // returns "City"
When I change the key to "City1" every thing works as expected.
Mage::helper('mymodule')->__('City1') // returns "Stadt"
After this I searched the German translation csv files (provided by the German Magento Community) for a translation for the key "City" and found one in the "adminhtml module".
Mage::helper('adminhtml')->__('City') // returns "Stadt"
So this also works as expected.
I don't know what I'm doing wrong. As I said the same behavior occurs for the string "Store".
Any ideas on this?
Finally I solved the translation problem. The reason was a wrong configuration in the config.xml. I found it out by debugging the code where Magento reads in the translation files. When this happens there's a parameter called scope which is read from one of the XML elements of the config.xml file.
This element should normally have the name of the module, e.g. <MyCompany_MyModule>. In the tutorial I followed to configure the translation, this XML-element was named <translations> which was wrong.
I guess that this might have been correct for an earlier version of Magento. What made it hard to find out was that the errors only occur for keys which were also defined in other modules's translation files. Keys which were only defined in my translation file worked as expected.
An correct configuration should look like this.
<frontend>
...
<translate>
<modules>
<MyCompany_MyModule>
<files>
<default>MyCompany_MyModule.csv</default>
</files>
</MyCompany_MyModule>
</modules>
</translate>
...
</frontend>
<adminhtml>
...
<translate>
<modules>
<MyCompany_MyModule>
<files>
<default>MyCompany_MyModule.csv</default>
</files>
</MyCompany_MyModule>
</modules>
</translate>
...
</adminhtml>
Hard to say without having your code at hand, but my guess would be that the translation scope of your module somehow gets lost (for whatever reason) causing Magento to fallback.
Afaik, in Magento 1.6.2.0 the following translation files also define the key City:
/app/locale/<language>_<region>/Mage_Checkout.csv
/app/locale/<language>_<region>/Mage_Customer.csv
/app/locale/<language>_<region>/Mage_Persistent.csv
/app/locale/<language>_<region>/Mage_Sales.csv
/app/locale/<language>_<region>/Mage_Shipping.csv
/app/locale/<language>_<region>/Mage_XmlConnect.csv
I'd try to change the translation for City in these .csv files one by one, to find out where the translation in question is actually coming from.
Once you found the file to which Magento is falling back, you also know, which translation scope you need to override, to force your translation of City to be used.
For example, if you find changing the translation in Mage_Shipping.csv does take affect, then you edit your translation file (My_Module.csv) to contain
"Mage_Shipping::City","Stadt"
I am using extension
http://www.magentocommerce.com/magento-connect/eitai2001/extension/1468/order-status/reviews#reviews
of magento which provide a lot of order status..but my need is limited ..so i want to remove some status from my order-status list... how can i do this..please help
Thanks!
Edited
I made change in config.xml
If I comment any order-status ... like this
<!--<processing_cc_settled translate="label"><label>Processing - Credit Card has been Settled</label></processing_cc_settled>-->
but in combobox(where status shows in admin site )still processing_cc_settled appears at the same place where Processing - Credit Card has been Settled showing up before commenting
If this is the same extension that I have seen installed one client's site then it should have a config.xml file included in its /etc subdirectory (NOTE: not the global /app/etc but somwhere in the /app/code/community/ folder). In this file you will find definitions for all the additional statuses. Just comment out the ones you don't want. You can also change the ones that you leave so that they are better suited to your needs.
CLARIFICATION:
Here's a piece of my config.xml:
<config>
<modules>
<Mage_Sales_Community>
<version>0.1.2</version>
</Mage_Sales_Community>
</modules>
<global>
<sales>
<order>
<statuses>
<!--Complete Status Descriptions-->
<complete translate="label"><label>Dispatched</label></complete>
<!--Cancelled Status Descriptions-->
<canceled translate="label"><label>Suspended</label></canceled>
<!--<canceled_discontinued translate="label"><label>Suspended - No stock</label></canceled_discontinued> -->
<!-- /* Additional custom statuses will go here */ -->
<!-- Format of a status description is <name_of_status translate="label"><label>Name of Status</label?</name_of_status> -->
</statuses>
</order>
</sales>
</global>
</config>
Note that complete and canceled have a different label defined. There is also a canceled_discontinued status, but it is not used as the whole entry is commented out. If the entry stays on the order comments dropdown after you have commented it make sure that you have refreshed the cache...
I add/remove magento statuses in install scripts, using something like below:
<?php
$installer = $this;
/*
Possible states:
Mage_Sales_Model_Order::STATE_CANCELED
Mage_Sales_Model_Order::STATE_CLOSED
Mage_Sales_Model_Order::STATE_COMPLETE
Mage_Sales_Model_Order::STATE_HOLDED
Mage_Sales_Model_Order::STATE_NEW
Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW
Mage_Sales_Model_Order::STATE_PENDING_PAYMENT
Mage_Sales_Model_Order::STATE_PROCESSING
*/
$installer->startSetup();
// Get status model
$status = Mage::getModel('sales/order_status');
// Delete some statuses
$status->setStatus('processing_cc_settled')->delete();
$status->setStatus('another_status_code_to_delete')->delete();
//Add a new status
$status->setStatus('holded_cc_error')
->setLabel('On Hold: CC Error')
->assignState(Mage_Sales_Model_Order::STATE_HOLDED)
//for example, use any available existing state from above
->save();
//To set an order to this status:
//$order->setData('state', "holded");
//$order->setStatus("holded_cc_error");
//$order->save();
$installer->endSetup();