Magento Multi language store with varnish

2020-05-28 19:13发布

问题:

How Multi-Language Magento store work with Varnish. Is there any configuration available in varnish,so we can create cache base on cookies?

回答1:

If you don't mind the languages being at different urls, Turpentine can handle this for you: https://github.com/nexcess/magento-turpentine/issues/36

If you want them to behave as they do out of the box, lets keep going.

You have to modify how varnish generates the has in your VCL Reference: https://www.varnish-cache.org/trac/wiki/VCLExampleCachingLoggedInUsers

We would modify this to also take into account the store cookie that Magento sets based on the language selector. (Following the behavior here: http://demo.magentocommerce.com) Unfortunately this gets tricky as Varnish tends to either not pass cookies back to the server or not cache things when it sees cookies flying around

This would have Varnish cache based on the value of the cookie as well as the default url and host:

sub vcl_hash {
        hash_data(req.url);
        hash_data(req.http.host);

        if (req.http.Cookie ~ "(?:^|;\s*)(?:store=(.*?))(?:;|$)"){
                hash_data(regsub(req.http.Cookie, "(?:^|;\s*)(?:store=(.*?))(?:;|$)"));
        }

        return (hash);
}

But, with this method you might have to tweak the rest of your VCL to cache the page properly AND send the cookies back to the server

Another option is to use the cookie to vary caching on an arbitrary header, lets call it X-Mage-Lang:

sub vcl_fetch {
    #can do this better with regex
    if (req.http.Cookie ~ "(?:^|;\s*)(?:store=(.*?))(?:;|$)"){
        if (!beresp.http.Vary) { # no Vary at all
            set beresp.http.Vary = "X-Mage-Lang";
        } elseif (beresp.http.Vary !~ "X-Mage-Lang") { # add to existing Vary
            set beresp.http.Vary = beresp.http.Vary + ", X-Mage-Lang";
        }
    }
    # comment this out if you don't want the client to know your classification
    set beresp.http.X-Mage-Lang = regsub(req.http.Cookie, "(?:^|;\s*)(?:store=(.*?))(?:;|$)");
}

This pattern is also used for device detection with varnish: https://github.com/varnish/varnish-devicedetect/blob/master/INSTALL.rst

Then, you would have to extend Mage_Core_Model_App to use this header instead of the 'store' cookie. In Magento CE 1.7 its _checkCookieStore :

protected function _checkCookieStore($type)
{
    if (!$this->getCookie()->get()) {
        return $this;
    }

    $store = $this->getCookie()->get(Mage_Core_Model_Store::COOKIE_NAME);
    if ($store && isset($this->_stores[$store])
        && $this->_stores[$store]->getId()
        && $this->_stores[$store]->getIsActive()) {
        if ($type == 'website'
            && $this->_stores[$store]->getWebsiteId() == $this->_stores[$this->_currentStore]->getWebsiteId()) {
            $this->_currentStore = $store;
        }
        if ($type == 'group'
            && $this->_stores[$store]->getGroupId() == $this->_stores[$this->_currentStore]->getGroupId()) {
            $this->_currentStore = $store;
        }
        if ($type == 'store') {
            $this->_currentStore = $store;
        }
    }
    return $this;
}

You would set the current store on $_SERVER['X-Mage-Lang'] instead of the cookie



回答2:

Add Following lines in Varnish Config,

if(beresp.http.Set-Cookie) {
     return (hit_for_pass); 
}