Magento - Limit title length for seo - magento

I'd really like to limit the title length on products in Magento.
What I've tried is adding 'maxlength' => 65 somewhere in \app\code\core\Mage\Adminhtml\Block\, without success.
Does someone know how to add this feature? In HTML it will just be adding length="65" maxlength="65".
Thanks for all affords. :)

I don't have the platform available to give you a proper walkthrough on setting this up, but I should be able to get you in the right place. First of all, do not make changes in the app/code/core files. Any changes you would absolutely need to make to those files you should do by making a copy of lets say app/code/core/Mage/Sales/something.php to app/code/local/Mage/Sales/something.php. Magento knows to automatically use the code in local to override the code in core.
If you take a look at the source code for that page you'll see where the name form is:
<input id="name" name="product[name]" value="" class=" required-entry input-text required-entry" type="text"/> </td>
<td class="scope-label"><span class="nobr">[STORE VIEW]</span></td>
</tr>
What's going on here is you'll notice under class we have "required-entry input-text and, well, required-entry again. These are the validation tags defined in js/prototype/validation.js. You will need to add some custom validation to it, and add it to your template file (not in core, it can break when you upgrade).
You'll notice in validation.js a section
Validation.add('IsEmpty', '', function(v) {
In this section you can add your custom validation. Lets say:
//make sure these are unique, I'm not checking
['validate-length', 'Your input needs to be less than x characters.', function(v) {
if (v.length > x) return false;
}],
If you need help finding the template location, take a look at: Finding Correct Templates and Blocks in Magento. You'll simply add validate-length class such as: class="required-entry validate-length..."

After almost 10 hours of searching I gave the up the "best" way, and choose for the roundabout.
Simply add
document.getElementById("name").setAttribute("maxlength", "65");
document.getElementById("name").setAttribute("length", "65");
to app/design/adminhtml/default/default/template/catalog/wysiwyg/js.phtml

You can add javascript validator to the product's name attribute. To achieve this, you need to update attribute with special value for frontend class. Just create sql upgrade:
$this->updateAttribute(
Mage_Catalog_Model_Product::ENTITY,
'name',
array(
'frontend_class' => 'validate-length maximum-length-65',
'note' => 'Max length is 65 characters'
)
);

Related

I need to click this input only if it has "aria-checked ="true"

I need to click this input only if it has "aria-checked ="true"
<input class="mat-checkbox-input cdk-visually-hidden" type="checkbox" id="mat-checkbox-131-input" tabindex="0" aria-checked="true" style="" xpath="1">
Ruby:
aria_checked = true
if aria_checked = true
impressora_etiqueta = "//mat-checkbox[#id='mat-checkbox-23']/label/div"
page.find(:xpath, impressora_etiqueta).click
end
There are many ways to do what you want - simplest is probably
page.first('#mat-checkbox-23[aria-checked="true"]', minimum: 0)&.click
which will look for the first element with the given id and aria-checked = "true" and click it if one exists.
Note: the id in your test and sample HTML didn't match so I went the id from your test, adjust as needed. Also you have a class of cdk-visually-hidden shown -- If that's actually making the element not visible on the page, then this won't work and you'll need to add more surrounding HTML to your question with a better description of exactly what you're trying to do (you can't click on non-visible elements)

Finding an Image Icon Next to a Text Item in Watir-WebDriver

The context is I'm using watir-webdriver and I need to locate if an image appears prior to a particular item in a list.
More specifically, there is a section of the site that has articles uploaded to them. Those articles appear in a list. The structure looks like this:
<div id="article-resources"
<ul class="components">
...
<li>
<div class="component">
<img src="some/path/article.png">
<div class="replies">
<label>Replies</label>
</div>
<div class="subject">
Saving the Day
</div>
</div>
</li>
...
</ul>
</div>
Each article appears as a separate li item. (The ellipses above are just meant to indicate I can have lots of liste items.)
What I want our automation to do is find out if the article has been appropriately given the image article.png. The trick is I need to make sure the actual article -- in the above case, "Saving the Day" -- has the image next to it. I can't just check for the image because there will be multiples.
So I figured I had to use xpath to solve this. Using Firefox to help look at the xpath gave me this:
id("article-resources")/x:ul/x:li[2]/x:div/x:img
That does me no good, though, because the key discriminator seems to be the li[2], but I can't count on this article always being the second in the list.
So I tried this:
article_image = '//div[#class="component"]/a[contains(.,"Saving the Day")]/../img'
#browser.image(:xpath => article_image).exist?.should be_true
The output I get is:
expected: true value
got: false (RSpec::Expectations::ExpectationNotMetError)
So it's not finding the image which likely means I'm doing something wrong since I'm certain the test is on the correct page.
My thinking was I could use the above to get any link (a) tags in the div area referenced as class "component". Check if the link has the text and then "back up" one level to see if an image is there.
I'm not even checking the exact image, which I probably should be. I'm just checking if there's an image at all.
So I guess my questions are:
What am I doing wrong with my XPath?
Is this even the best way to solve this problem?
Using Watir
There are a couple of approaches possible.
One way would be find the link, go up to the component div and then check for the image:
browser.link(:text => 'Saving the Day').parent.parent.image.present?
or
browser.div(:class => 'subject', :text => 'Saving the Day').parent.image.present?
Another approach, which is a little more robust to changes, is to find the component div that contains the link:
browser.divs(:class => 'component').find { |component|
component.div(:class => 'subject', :text => 'Saving the Day').exists?
}.image.present?
Using XPath
The above could of course be done through xpath as well.
Here is your corrected xpath:
article_image = '//div[#class="component"]//a[contains(.,"Saving the Day")]/../../img'
puts browser.image(:xpath => article_image).present?
Or alternatively:
article_image = '//a[contains(.,"Saving the Day")]/../../img'
browser.image(:xpath => article_image).present?
Again, there is also the top down approach:
article_image = '//div[#class="component"][//a[contains(.,"Saving the Day")]]/img'
browser.image(:xpath => article_image).present?
You can read more about these approaches and other options in the book Watirways.

Problems Saving Large Number of Attribute Option Labels in Magento

I'm running into a problem in a Magento system where saving a large number of attributes either doesn't work at all, or only partially works. It appears to be a javascript related issue, and I was hoping someone on Stack Overflow had some "known science" for dealing with this situation, or could point me in the right direction.
The basic problem is, the Magento system in question has over 250 color attribute option labels. If an admin user attempts to manage these by doing the following
Navigating to Catalog -> Attributes -> Manage Attributes
Selecting the color attributes
Clicking on the Manage Label/Options tab
Editing the last Label Option
Clicking "Save and Continue Edit"
One of two things happens.
In Google Chrome on OS X, the button sticks in the "depressed" state, and after a period of time Google Chrome's "This page is not responsive" kill dialog comes up.
In a mozilla based browser on OS X, clicking the button makes the browser "think" for a bit, but it eventually submits the form. However, only a partial list of attribute labels is posted to the admin controller. This means the user can only edit the first 75 - 100 labels, since the other labels are never submitted.
I have reports from windows users describing the second behavior as well (browsers are non-specific)
The obvious answers are to either investigate the poorly performing javascript, or (Grouch Marx style) "don't do that". Before I spend the time profiling/excavating the javascript on that page, I was hoping there was some known fix for this, or specific knowledge as to what was causing the problem.
Magento CE 1.7.x, if it maters.
Update: The Javascript performance issues are a red herring. They're caused by the massive number of input fields being iterated through in
js/prototype/validation.js
Specifically in this try catch block
try {
if(this.options.stopOnFirst) {
result = Form.getElements(this.form).all(function(elm) {
if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
return true;
}
return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
}, this);
} else {
result = Form.getElements(this.form).collect(function(elm) {
if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) {
return true;
}
return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback});
}, this).all();
}
} catch (e) {
}
However, even if I short circuit this and have the function return true, the behavior of not saving all the labels persists.
You can try the variable max_input_vars (introduced in PHP 5.3.9), by default it's 1000 so that should be enough, but maybe your configuration uses a lower amount. But I imagine the form just doesn't get through due to the major performance issues you're experiencing.
About the option labels: do they by any change have an uploader for an attribute-image? We had the exact same problem when we installed the GoMage Advanced Navigation extension on a shop with over 300 manufacturer options (the extension uses Magento's built-in Flash-uploader).
We didn't have the extension for that feature so I disabled the uploader, but the extreme performance decrease was definitely in the 300 Flash-movies being loaded. Maybe you can try lazyloading the uploader on a per-option basis by inserting a button or link instead of the movie.
Hope this points you in the right (or exact) direction.
[Working SOLUTION]
Hello as Alan Storm mentioned, this ussue is related with the JS logic, that handles the validation of the option label inputs. I had this problem on a project of one of my clents and I wrote simple extension, that solves it.
You can dowload the exntesion for here: https://github.com/Jarlssen/Jarlssen_FasterAttributeOptionEdit
Basically the extension replaces the original option template with mine template. In my template I rewrote most of the JS in the bottom of the template and replaced the form inputs with div elements ( pseudo inputs ), so when the administrator click on the pseudo input, then its replaced with the real input. In this way we avoid validating all the inputs and we validate only edited and the new added entries. The extension works well if you add options on chunks, for example 500 entries per attribute save.
Hope, that helps.
Additional information: http://www.jarlssen.de/blog/2014/05/07/magento-timeout-saving-attribute-options-type-multiple-select-and-dropdown
Quick look at the pseudo generation code:
<tr class="option-row">
<?php foreach ($this->getStores() as $_store): ?>
<td>
<div class="replace-content pseudo-input input-text <?php if($_store->getId()==0): ?> required-option<?php endif; ?>" id="option[value][<?php echo $_value->getId() ?>][<?php echo $_store->getId() ?>]"><?php echo $_value->getData('store' . $_store->getId()) ?></div>
</td>
<?php endforeach; ?>
<td>
<div class="replace-content pseudo-input" id="option[order][<?php echo $_value->getId() ?>]"><?php echo $_value->getSortOrder() ?></div>
</td>
<td class="a-center default-checkbox">
<div id="option_<?php echo $_value->getId() ?>" class="checkbox-radio-container replace-content">
<?php if($_value->getChecked()) : ?>
<input class="input-radio" type="<?php echo $defaultChooserInputType; ?>" name="default[]" value="<?php echo $_value->getId() ?>" checked <?php if ($this->getReadOnly()):?> disabled="disabled"<?php endif;?>/>
<?php else : ?>
<?php if('radio' == $defaultChooserInputType) : ?>
<span class="fake-radio"></span>
<?php else : ?>
<span class="fake-checkbox"></span>
<?php endif; ?>
<?php endif; ?>
</div>
</td>
<td class="a-left actions-column" id="delete_button_container_<?php echo $_value->getId() ?>">
<div id="option[delete][<?php echo $_value->getId() ?>]" title="<?php echo $this->__('Delete') ?>" class="scalable left pseudo-delete-option">
<span class="pseudo-delete-button" option_id="<?php echo $_value->getId(); ?>">
<span>
<span><?php echo $this->__('Delete') ?></span>
</span>
</span>
</div>
</td>
</tr>
I had exactly this problem (POST truncated) and it comes from a suhosin patch that has a too little POST limit. (or the standard PHP post_max_size)
In your php.ini check these values and increase their values if needed (and restart apache) :
post_max_size
suhosin.post.max_vars
suhosin.request.max_vars
For your second probleme (JS performance issue), I can't help you
Sorry!!
I went through this same problem , solution follows below.
Explanation of the problem
problem
A customer has a very large base of tires that also have many cars added to the same , thereby to migrate moorings between tires and vehicles only 255 characters of the attributes of ids were inserted into the table with it causing error in the migration.
The magento inserts a string with ids separated by ,
The problem occurred in the table "catalog_product_entity_varchar" in the value field which by default is 255 characters if I put text and resolved .
Note : I know you modify the DB is not nice but unfortunately had to perform this operation.
Example product
Tire 175 / 65R14
-> Make ( + - 200 options)
-> Model (+ - 4mil options)
-> Series (+ - 15mil options)
-> Year
-> ...
att,
Same problem here. I solved with BELVG module "Attribute Pagination" : http://blog.belvg.com/attribute-admin-page-pagination-in-magento.html
It works properly.
Hope that helps.
Open your server's php.ini, search for max_input_vars and set its value to greater than 2500 will solve your problem
; How many GET/POST/COOKIE input variables may be accepted
max_input_vars = 5000

Why is #Html.Label() removing some characters

When I use the following code in my razor view it renders <label for=""> someText</label> and not <label for="">1. someText</label> but I can't figure out why 1. is removed while rendering.
#Html.Label(String.Format("{0}. someText",1))
Edit:
The following code renders <label for="">1# someText</label> as expected.
#Html.Label(String.Format("{0}# someText",1))
You are misusing the Html.Label method. It is for:
Returns an HTML label element and the property name of the property
that is represented by the specified expression.
That's why it gets confused if you have a point . in the first parameter because it expects a property expression there.
However, you can use the second overload:
#Html.Label("", String.Format("{0}. someText",1))
Or just write out the HTML:
<label>#String.Format("{0}. someText", 1)</label>
You can avoid using the "Html Helper's label" and directly use html "label" and place whatever you want to display correctly. It can also save some time ;)
The syntax which you are using is wrong or We can say that this is not a way to use property with RAZOR syntax.
You ca use this that may be help full for you.
**
#Html.LabelFor(model => model.PropertyName,
String.Format("{0}. " + #Model.PropertyName.ToString() + ",1))
**
I was using this for a data table that contained a double (Lat/Long) and saw this same problem. Thanks for the tips (I am not allowed to comment).
For me, the problem was solved ..
#foreach (var cell in item.ItemArray)
{
<td>
#Html.Label("",cell.ToString().Trim())
</td>
}

How to check whether date widget is empty?

I tried to check whether date widget is empty. If it is empty, it shouldn't show up.
<div class="field"
tal:define="value widget/value;
valueexists python:value not in (None, '',);
label widget/label"
tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',) and valueexists">
Problem is the below expression doesn't seem able to check for date:
python:value not in (None, '',)
Why not something like:
<div class="field"
tal:define="value widget/value;
label widget/label"
tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description',
'title', 'description',) and value">
...
</div>
Testing for specific values of widget/value seems destined to cause trouble.
I'm not sure I understood your question correctly, but I'd also like to suggest jQuery as a way to check and conditionally hide (remove) a widget, if it's for aesthetic reasons.

Resources