Re: Ultimate SEO 2.200 (new features) [Support Thread]
Hi all,
I've been using Ultimate SEO for a while now and now and I am finally happy with it after figuring out how to configure it to my needs. I have recently added directory-based language differentiation for SEO and clarification (since I have both Dutch and English versions of all pages), and I am trying to correctly inform search engines about the different forms of my pages in the different languages, using 'canonical' and 'hreflang' in common/html_header.php
On fixed-url pages this works perfectly how I want it:
HTML Code:
<link rel="canonical" href="http://art.horisense.com/en/" />
<link rel="alternate" href="http://art.horisense.com/" hreflang="x-default" />
<link rel="alternate" href="http://art.horisense.com/nl/" hreflang="nl" />
<link rel="alternate" href="http://art.horisense.com/en/" hreflang="en" />
However, on product- and category pages I cannot notify about any other language pages than the active language:
HTML Code:
<link rel="canonical" href="http://art.horisense.com/en/canvas-c-8/canvas-40x30-pastel-poppy-dancer-p-31.html " />
<link rel="alternate" href="http://art.horisense.com/-p-31" hreflang="x-default" />
<link rel="alternate" href="http://art.horisense.com/en/canvas-c-8/canvas-40x30-pastel-poppy-dancer-p-31.html" hreflang="en" />
This is because the 'zen_href_link' and $seo_urls->href_link functions do not have a language choice. I even tried changing $_SESSION['language'], $_SESSION['language_code'], $_SESSION['language_id'] and reconstructing $seo_urls with the other language id, but zen_href_link still kept giving the url with the active language only. It seems the only way is to completely reinitialize all language-specific constants.
Any ideas on the best way to get the page url from another language than the active one?
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Quote:
Originally Posted by
Mohandas
Hi all,
I've been using Ultimate SEO for a while now and now and I am finally happy with it after figuring out how to configure it to my needs. I have recently added directory-based language differentiation for SEO and clarification (since I have both Dutch and English versions of all pages)...
Nice. Please consider contributing your changes! If you send them my way (PM or EMAIL) I will look over them further and consider them for inclusion in a future version :smile:
Quote:
Originally Posted by
Mohandas
...
However, on product- and category pages I cannot notify about any other language pages than the active language ...
If you turn off "automatic redirects", you can use something like the following:
Code:
$tmp_lng = new language();
foreach($tmp_lng->catalog_languages as $lng) {
// Initialize a new generator for a specific language (by language_id).
${'usu_' . $lng['code']} = new SEO_URL($lng['id']);
// Create a link using the generator for a specific language (make sure to define $excludeParams).
${'link_' . $lng['code']} = ${'usu_' . $lng['code']}->href_link($current_page, zen_get_all_get_params($excludeParams), $request_type, false);
// Alternate available for the specified language.
if(${'link_' . $lng['code']} !== null) {
// Do something with the link (such as add an alternate).
}
unset(${'usu_' . $lng['code']}, ${'link_' . $lng['code']});
}
unset($tml_lng, $lng);
If you installed the "Multilingual Ez-Pages" mod, you will need to change the code on line 652 and 930 of 'seo_url.php' to replace (int)$_SESSION['languages_id'] with $this->languages_id. This only affects generating alternate URLs for a language other than the current language.
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Quote:
Originally Posted by
lhungil
Nice. Please consider contributing your changes! If you send them my way (PM or EMAIL) I will look over them further and consider them for inclusion in a future version :smile:
I can't guarantee compatibility with other settings and plugins though, but it mainly involves adding this to .htaccess before the start of the Ultimate SEO rewrite rules:
PHP Code:
RewriteRule ^(en|nl)/(.*)$ $2?language=$1 [QSA,L]
and in functions/html_output.php change:
PHP Code:
$href_link = $seo_urls->href_link($page, $parameters, $connection, $add_session_id, $static, $use_dir_ws_catalog);
to
PHP Code:
// adds the current language as a directory to all links,
if (isset($_SESSION['languages_code'])){
$language_tag_content=$_SESSION['languages_code'];
}else{
// if no $_SESSION['languages_code'] parameter is found, the default language is added to all links:
$language_tag_content=DEFAULT_LANGUAGE;
}
// give preference over language code in the language variable
// the language GET variable is extracted and removed in case a language parameter is present in the url
// (which is the normal case since .htaccess converts the language directory into a language GET variable):
if (strstr($parameters,'language=')){
$language_pos = strrpos ( $parameters , 'language=');
$language_code_pos = $language_pos + 9;
$language_tag_content = substr ( $parameters , $language_code_pos ,2 );
// remove language tag from parameters:
$parameters = substr ( $parameters , 0 , $language_pos) . substr ( $parameters , $language_pos+11);
}
// generate the link without language parameter:
$href_link = $seo_urls->href_link($page, $parameters, $connection, $add_session_id, $static, $use_dir_ws_catalog);
if($href_link === null) {
$href_link = original_zen_href_link($page, $parameters, $connection, $add_session_id, $search_engine_safe, $static, $use_dir_ws_catalog);
$href_link = str_replace('%20','+',$href_link);
$href_link = str_replace('&','&',$href_link);
}
// include the language tag content as a directory in the link url. htaccess will convert this into a regular language GET variable
if (strstr($href_link,HTTPS_SERVER.DIR_WS_HTTPS_CATALOG)){
$href_link = HTTPS_SERVER.DIR_WS_HTTPS_CATALOG . $language_tag_content .'/'. substr ( $href_link , strlen(HTTPS_SERVER.DIR_WS_HTTPS_CATALOG));
}else{
if (strstr($href_link,HTTP_SERVER.DIR_WS_CATALOG)){
$href_link = HTTP_SERVER.DIR_WS_CATALOG . $language_tag_content .'/'. substr ( $href_link , strlen(HTTP_SERVER.DIR_WS_CATALOG) );
}
}
Quote:
If you turn off "automatic redirects", you can use something like the following:
Code:
$tmp_lng = new language();
foreach($tmp_lng->catalog_languages as $lng) {
// Initialize a new generator for a specific language (by language_id).
${'usu_' . $lng['code']} = new SEO_URL($lng['id']);
// Create a link using the generator for a specific language (make sure to define $excludeParams).
${'link_' . $lng['code']} = ${'usu_' . $lng['code']}->href_link($current_page, zen_get_all_get_params($excludeParams), $request_type, false);
// Alternate available for the specified language.
if(${'link_' . $lng['code']} !== null) {
// Do something with the link (such as add an alternate).
}
unset(${'usu_' . $lng['code']}, ${'link_' . $lng['code']});
}
unset($tml_lng, $lng);
Your suggestion was sort of what I tried already and doesn't work.
But I found out that the problem was caused by the cache. If I turn off the seo url cache it works!
And also it was helpful to use this way of looping through the languages in order to find the id and the language code together.
I changed my mind about the default language page btw. I use it also for the social media buttons, to combine the like/share counts for all languages. I thought it would be a good idea to have a very short url, so it leaves more room in tweets. However, on second thought I have now chosen to use a slightly shortened version of the English url for the x-default language page and the social media tweets/shares/likes (regardless of the chosen language):
HTML Code:
<link rel="canonical" href="http://art.horisense.com/nl/canvas-c-8/canvas-40x30-pastel-papaverdanseres-p-31.html" />
<link rel="alternate" href="http://art.horisense.com/canvas-c-8/canvas-40x30-pastel-poppy-dancer-p-31/" hreflang="x-default" />
<link rel="alternate" href="http://art.horisense.com/nl/canvas-c-8/canvas-40x30-pastel-papaverdanseres-p-31.html" hreflang="nl" />
<link rel="alternate" href="http://art.horisense.com/en/canvas-c-8/canvas-40x30-pastel-poppy-dancer-p-31.html" hreflang="en" />
In this way, I may still at least benefit from the english keywords in the url, when my product url's are shared in tweets.
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Quote:
Originally Posted by
Mohandas
...
Your suggestion was sort of what I tried already and doesn't work.
But I found out that the problem was caused by the cache. If I turn off the seo url cache it works!
And also it was helpful to use this way of looping through the languages in order to find the id and the language code together.
...
Ahh, yes - the memory cache assumes the same language for each page request. Forgot about that one. Thanks for reporting back! I'll have to take a look at some changes in a future release :)
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Quote:
Originally Posted by
lhungil
Ahh, yes - the memory cache assumes the same language for each page request. Forgot about that one. Thanks for reporting back! I'll have to take a look at some changes in a future release :)
I used this caching in memory:
PHP Code:
$this->cache['PRODUCTS'][$pID][$this->languages_id] = $pName;
and
PHP Code:
defined('PRODUCT_NAME_' . $pID . '_lng_' . $this->languages_id)
and so on.
Now I refused to use the constants for caching (strange idea).
And also refused to create a complete in-memory cache every time a class construct. Need to conserve memory.
When you need something - then put in the cache. Cache on demand.
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Quote:
Originally Posted by
a_berezin
I used this caching in memory:
PHP Code:
$this->cache['PRODUCTS'][$pID][$this->languages_id] = $pName;
and
PHP Code:
defined('PRODUCT_NAME_' . $pID . '_lng_' . $this->languages_id)
and so on.
Now I refused to use the constants for caching (strange idea).
And also refused to create a complete in-memory cache every time a class construct. Need to conserve memory.
When you need something - then put in the cache. Cache on demand.
Yup, The in memory caching code is some of the last remaining inherited code. The inherited code works how you mentioned - minus the language (including both in memory storage using constants and storage using an array).
There are three configuration options for the in memory caches... None, array only, array + constant / SQL... I typically enable the array only based in memory cache. In most cases if you need the constant / SQL method you are better off moving to a different hosting environment (or provider).
To disable the constant based memory cache (loads all items into memory when the class is created) disable the "product cache", "manufacturer cache", "category cache", etc. Leave the "global" cache option enabled. Global is not quite the right word, but is the one used in the configuration at this time.
For Mohandas` scenario using only the array based cache (with no other code changes) and disabling "automatic redirects" should work. My snippet earlier was thrown together on a system with only the array cache enabled.
If one wants to enable the larger "constant" based caching mechanism and needs to be able to pull the same URL for different languages... Changes such as those posted by a_berezin will be needed (thank you for posting).
Removing and / or refactoring the existing code handling caching is part of the "todo" list for the next major release. The constant based caches may be disabled by default in the next minor release... And may be removed completely in favor of some alternative methods...
1 Attachment(s)
Re: Ultimate SEO 2.200 (new features) [Support Thread]
zencart: v1.5.1
USEO: V2.212
Problem: (including all products, new products....)
When set USEO on (ex: domain/products_new.html), the pages were available. However, google (webmaster tools -> fetch as google) shown that the page status was 404, and the firebug said it was 200. If visit the page as domain/index.php?main_page=products_new, there was no issues.
Attachment 12893
I think it may be a .htaccess problem, but I don't understand it. Could anyone help?
Code:
###############################################################################
# Common directives
###############################################################################
# NOTE: Replace /shop/ with the relative web path of your catalog in the "Rewrite Base" line below:
#301 redirects
RewriteEngine On
RewriteCond %{HTTP_HOST} ^my domain name [nc]
RewriteRule ^(.*) http://www.my domain name/$1 [R=301,L]
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
#producttags
RewriteRule ^producttags/([-\w]+)/$ index\.php?main_page=producttags&letter=$1&%{QUERY_STRING} [L]
RewriteRule ^producttags/([\w])/([0-9]+).html$ index\.php?main_page=producttags&letter=$1&page=$2&%{QUERY_STRING} [L]
RewriteRule ^wishlist/$ index\.php?main_page=wishlist [L]
RewriteRule ^wishlist/([\w])/$ index\.php?main_page=wishlist&letter=$1&%{QUERY_STRING} [L]
RewriteRule ^wishlist/([\w])/([0-9]+).html$ index\.php?main_page=wishlist&letter=$1&page=$2&%{QUERY_STRING} [L]
# For Open Operations Info Manager
RewriteRule ^(.*)-i-([0-9]+).html$ index\.php?main_page=info_manager&pages_id=$2&%{QUERY_STRING} [L]
###############################################################################
# Start Ultimate SEO URLs
###############################################################################
# Handles the new URL formats
RewriteRule ^(.*)-c-([0-9_]+)/(.*)-p-([0-9]+)(.*)$ index\.php?main_page=product_info&products_id=$4&cPath=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-c-([0-9_]+)/(.*)-pi-([0-9]+)(.*)$ index\.php?main_page=popup_image&pID=$4&cPath=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-c-([0-9_]+)/(.*)-pr-([0-9]+)(.*)$ index\.php?main_page=product_reviews&products_id=$4&cPath=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-c-([0-9_]+)/(.*)-pri-([0-9]+)(.*)$ index\.php?main_page=product_reviews_info&products_id=$4&cPath=$2&%{QUERY_STRING} [L]
# Original (unchanged) URL formats
RewriteRule ^(.*)-p-([0-9]+)(.*)$ index\.php?main_page=product_info&products_id=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-m-([0-9]+)(.*)$ index\.php?main_page=index&manufacturers_id=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-pi-([0-9]+)(.*)$ index\.php?main_page=popup_image&pID=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-pr-([0-9]+)(.*)$ index\.php?main_page=product_reviews&products_id=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-pri-([0-9]+)(.*)$ index\.php?main_page=product_reviews_info&products_id=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-ezp-([0-9]+)(.*)$ index\.php?main_page=page&id=$2&%{QUERY_STRING} [L]
RewriteRule ^(.*)-c-([0-9_]+)(.*)$ index\.php?main_page=index&cPath=$2&%{QUERY_STRING} [L]
# All other pages
# Don't rewrite real files or directories
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ index\.php?main_page=$1&%{QUERY_STRING} [L]
RewriteRule ^news(.*)$ index.php?main_page=news&$1 [E=VAR1:$1,QSA,L]
Re: Ultimate SEO 2.200 (new features) [Support Thread]
a_berezin and lhungil thank you so much for the detailed help. Yes it was indeed okay to leave on the global cache when I turned off all the page-specific cache options. As far as I could see in the code, indeed the database cache is differentiating between languages. Language differentiation is just not included in naming the constants nor in $this->cache.
I think I also managed to implement the suggestion by a_berezin to modify the constants and memory cache, by modifying all definitions and queries with respect to PRODUCT_NAME_ AND $this->cache['PRODUCTS'] in the functions 'get_product_name', 'get_product_canonical' and 'generate_products_cache' to include a language id. I now finally get the different language urls even when I turn on product name cache. I will do the same for the categories, etc.
And I guess what a_berezin tried to say is that every time a seo class is constructed, all product names are read from the database and put into memory (constant) cache. This seems quite a lot of unnecessary overhead process and memory since most of the names will not be used.
It seems that, in order to replace that by on demand caching, the function get_product_name will need to not only read the product name from the database if it is not cached yet, but also put in the cache at that moment. Am I correct and is this the only thing that would need to be added when removing 'generate_products_cache()' from class construction? Or would there be more modifications necessary?
Re: Ultimate SEO 2.200 (new features) [Support Thread]
I'm sorry that I answer here, in the discussion of the module from lhungil.
Quote:
Originally Posted by
Mohandas
It seems that, in order to replace that by on demand caching, the function get_product_name will need to not only read the product name from the database if it is not cached yet, but also put in the cache at that moment. Am I correct and is this the only thing that would need to be added when removing 'generate_products_cache()' from class construction?
Yes, that's exactly what I'm doing. In get_product_name I check whether the name with requested products_id and current language_id in the cache, if not - read from the database and put it in db_cache/Memcache and (optional) in memory cache.
Also I use very simple structure of DB Cache Table:
PHP Code:
$insert_cache_table = "CREATE TABLE " . TABLE_SEO_CACHE . " (
cache_name char(32) NOT NULL,
cache_data text NOT NULL,
cache_created timestamp NOT NULL,
PRIMARY KEY (cache_name),
KEY idx_cache_created (cache_created)
) ENGINE=MyISAM;";
Re: Ultimate SEO 2.200 (new features) [Support Thread]
Hi
I have an issue that seems a bit unusual and I was hoping somebody might be able to offer some advice as to what's going on.
I'm trying to install Ultimate SEO onto my development site. Its Zen Cart 1.5.1 and the latest USEO (2.212). No .htaccess file was being used and none of the core zen files had been edited so the install was simple - copy over the amended files, copy over the new files, edit the .htaccess file (RewriteBase / to match the location of Zen which is installed to the root of the domain), upload .htaccess, login and finish the install. The install said it was successful.
If I browse to a category or product page the URL is re-written as I expected but the page takes ages to load and seems to be missing all the styling and scripts. Using the developer tools in Chrome I can see a category page takes 20.6 seconds to load, makes 67 requests and transfers 1.6Mb of data.
As a comparison, the same page on the live site (or the dev site if I disable USEO) takes 1.52 seconds to load, makes 75 requests and transfers 96.5Kb of data.
I'm at a bit of a loss as to what's going on. Has anyone else seen this or have any idea as to what the issue might be?
Thanks in advance!
Tom