Apache two apps one domain share language /en - Magento & Wordpress - php

We have Wordpress in the root / in a physical subfolder /wp and Magento in /products.
We are wanting to make the sites multi-language using sub folders e.g domain.com/en
The problem arises as magento appends the store code (language) after the url so we have
domain.com/en (wordpress)
domain.com/products/en (magento)
Naturally we would like
domain.com/en
domain.com/en/products
Now it's very easy to make it work with some rewrite rule
RewriteRule ^(.*)/products/?(.*)$ /products/$1 [L]
But still we have an issue as Magento generates the links as /products/en it's possible to start modifying where these links are generated like in
\Magento\Store\Model\Store
In the _updatePathUseStoreView function, this doesn't seem to handle all links though
In general seems like a bad solution, another idea is to use Apache mod_substitute also seems bad practice, and overhead.
Another option is to have both apps in the root and have some lookup logic to see which url belongs to which app.
Any ideas for a setup that can purely use just Nginx/Apache. That does not compromise on having unique url's or regex'ing content.
This is my .htaccess in the root
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteCond %{REQUEST_URI} !^/wp/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{REQUEST_URI} !^/(.*)/products
RewriteRule ^(.*)$ /wp/$1
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ wp/index.php [L]
RewriteCond %{REQUEST_URI} ^/(.*)/products
RewriteRule ^(.*)$ /products/index.php [L]
</IfModule>
The exact spec I'm trying to achieve is this.
Wordpress is installed in /wp , Magento in /products
Language codes via subfolders used on both sites to appear as /en/wordpress-page /en/products/magento-page
Attempt 1
Use base link URL entering /en/products there and keeping the base URL as /products
as the first request is forwarded I had to work the setEnv like so in the root .htaccess
RewriteCond %{REQUEST_URI} ^/(.*)/products
RewriteRule ^(.*)$ /products/index.php [E=MAGE_RUN_CODE:%1] [L]
then in /products/.htaccess
RewriteCond "%{ENV:REDIRECT_MAGE_RUN_CODE}"
RewriteRule .* - [E=MAGE_RUN_CODE:%{ENV:REDIRECT_MAGE_RUN_CODE}] [L]
I checked the code was coming through on index.php by doing
echo getenv('MAGE_RUN_CODE');
In my case the store code is "en" etc.. but the language switcher does not work it hits Magento but gets 404 even thought the store code is definitely coming through.

You only need some configuration from backoffice.
System => Configuration => General => Web => Url options
Add Store Code to Urls No
System => Configuration => General => Web => Unsecure
Base Link URL http://example.com/en/products/
System => Configuration => General => Web => Secure
Base Link URL https://example.com/en/products/
Then, add a rule in htaccess to set the correct store code:
SetEnvIf Host .*example.com/en* MAGE_RUN_CODE=en_store
SetEnvIf Host .*example.com/fr* MAGE_RUN_CODE=fr_store

What is the exact spec you're trying to achieve?
Do you have multiple pages like /products, and multiple languages like /en?
I did something similar at BXR.SU — I didn't like the way OpenGrok, my backend, was handling the URLs, so, I would automatically make my nginx fix the URLs on top of OpenGrok, seamlessly fixing the URLs presented to the user, whereas the backend would continue to use the old URLs (e.g., with the /xref/ for most pages, which I don't like, and was set to remove with nginx); this approach appears to be similar to your spec, where you want to do this on the front-end web-server without doing any modifications to the backend.
The approach is briefly described at nginx redirect loop, remove index.php from url, with the idea being that nginx has two types of redirects — internal, where the contents of the $uri variable gets changed (without any visibility to the user), and external, where a 301 Moved (or some such) response is provided to the client (and the user would then see the browser making a request with the new URL).
E.g., you may want to have something like the following:
location /en/ {
# issue an external redirect, unless we're here from an internal one
if ($request_uri ~ "^(/en)(/product)(.*)") {
return 301 $2$1$3; # external redirect
}
proxy_pass …;
}
location /products/ {
rewrite ^(/products/)(en/)(.*) $2$1$3 last; # internal redirect
…
}

Related

Redirect a Subdirectory and any following subdirectories

I am having an issue with a subdirectory that has many different paths, but on the new website we are no longer using that structure. The old website worked this way:
example.com/photos/photo-1
example.com/photos/photo-2
example.com/photos/photo-3
On our new site we are not using /photos, and my current redirect attempts have not worked
Redirect 301 /photos https://example.com/
ends up redirecting to
example.com/photo-1
example.com/photo-2
example.com/photo-3
Removing the photos subdirectory, but still attempting to access the subdirectory that follow it.
The desired result would be for any attempt to access example.com/photos or example.com/photos/* should redirect to homepage at example.com/
Any help would be appreciated.
This should do it.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^photos/(.+) https://example.com/ [R=301,L]
</IfModule>
This probably is the approach that makes most sense:
RewriteEngine on
RewriteRule ^/?photos/[^/]+/(.+)$ https://example.com/$1 [R=301]
It uses the rewriting module which means that has to be loaded into the http server. That is the standard setup, though.
In case it is not all subfolders that should get redirected you can name a pattern instead. This allows for exceptions. For example:
RewriteEngine on
RewriteRule ^/?photos/photo-\d/+(.+)$ https://example.com/$1 [R=301]
And in case both host are identical for the old and the new "site" you can use an internal redirection to simplify things:
RewriteEngine on
RewriteRule ^/?photos/photo-\d/+(.+)$ /$1 [R=301]
In general you should try to implement such rules in the actual http server's host configuration. And only use a distributed configuration file instead (".htaccess") if you have no access to the central configuration. Various reasons.

Two domains on same webspace but different content / language by htaccess and GET parameters

I need a rewrite rule or some other solution for accessing pages like
www.domain.com/feature.php?lang=de
from
www.domain.de/feature.php
which lies at the same webspace as
www.domain.com.
From the beginning:
I have a domain
www.domain.com
with multi language content which is triggered by a language GET parameter.
For instance:
www.domain.com/features.php?lang=fr
will load the french content from the database, whereas
www.domain.com/features.php
displays the default English content.
For SEO friendly clean urls I created the following universal htaccess rewrite rule:
RewriteRule ^/?(.*)/(.*).php /$2.php?lang=$1 [L,QSA]
This will make urls like
www.domain.com/features.php?lang=fr
be accessible from the SEO friendly version:
www.domain.com/fr/features.php
Also other languages like
www.domain.com/features.php?lang=it
are covered by this and can be accessed by the clean url
www.domain.com/it/features.php
What I need is a solution for the special case for the German language, because for the German language I have a dedicated domain called domain.de. So it should not be accessible by a path-url like
www.domain.com/de/features.php
as the other languages, but instead from
www.domain.de/features.php
I probably have to point the domain target of domain.de to the same webspace as domain.com, since they share the same php files, stylesheets and images.
I don't know how to edit the htaccess file to cover the .de domain as well.
Please consider, that in addition to the hidden lang parameter, there are some pages, which need to pass some GET parameters too. They don't need to be hidden. They just need to be passed. So for instance
www.domain.com/features.php?lang=de&a=1&b=2
should be accessible from
www.domain.de/features.php?a=1&b=2
My current htaccess RewriteRule already covers the additional parameters for the .com/x/ domain by [L,QSA] at the end. But I don't know how to set it up to cover access from the .de domain, including the ocationally occuring GET parameters.
It should be a universal solution. So I should not have to enter a line for every of my php files, but instead it should cover all php filenames, as the already existing RewriteRule from above already does for the .com domain.
Thanks.
I think, this should give you at least the starting point:
Options -Indexes
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.de$[OR]
RewriteCond %{HTTP_HOST} ^example.de$
RewriteRule ^/?(.*)$ http://www.example.com/de/$1 [R=301,L,QSA]
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^/?(.*)/(.*).php /$2.php?lang=$1 [L,QSA]

htaccess mod_rewrite redirect to directory without displaying on url

I have a site called www.example.com and I have my php files in it. I store all my working files in www.example.com/site. I want to view the site in www.example.com instead, without moving my site content. What can I do?
This is currently what I am typing in .htaccess. It will redirect my site to www.example.com/site but I think the url is ugly
RewriteEngine on
RewriteBase /
RewriteRule ^(/.*|)$ /magento$1 [NC,L]
Let me see if i understood this correctly.
You have a domanin, www.example.com, and on this domain you want to display the content of a directory, www.example.com/site !?
If this is the case then you need to change the document root
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteCond %{REQUEST_URI} !^/site
RewriteRule ^(.*)$ /site/$1 [L]
or
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ /site/$1 [L,NC]
There are 2 things you must consider :
If I understand your request, you are accessing some PHP files using www.example.com, but what you want is to access www.example.com/site, but without the /site, right ?
So basicaly, what you're looking for is NOT rewrite, it's just pointing your domain to the good folder, which is /site, right ?
If you're using Apache2, you have to edit your apache's configuration file in /etc/apache2/site-available/default (or remplace default with the name of the virtualhost you may have created).
In this file, look for the directive DocumentRoot. It should lead to the "root" directory of your pages (the one you access typing www.example.com)
I think you just have to append /site to this DocumentRoot and then reload your apache2 with service apache2 reload
You're website www.example.com will now lead to the correct directory.
If it's still not working, you must consider looking into magento's admin, because magento is rewriting url according to the Base URL you specify inside Admin / Configuration / general / web.
You'll have to modify Base_URL in both Secure and Un-Secure sections.
Then it should work fine.
I would comment out the Rewrite bloc you're using at the moment, or maybe I didn't fully undestand what you want to achieve.

Mod rewrite base URL

I have several domains that I want to all rewrite to one domain. I don't want it to redirect because I want the URL to look like what the user has entered in. For example if they enter www.example.com I want it to load the page from www.sample.com/default.php?from=example
I have worked a little with rewriting if you have www.site.com/var1/var2 making it load www.site.com/index.php?one=var1&two=var2
Is it possible to do what I am looking for just through the .htaccess file? I tried looking around and couldn't exactly find what I was looking for
Thanks
If the sites are hosted on different servers or don't share a common document root, then you'll have to rely on mod_proxy and you can use the P rewrite rule flag. For example, these rules in an htaccess file in www.example.com's document root:
RewriteCond %{HTTP_HOST} ([^.]+)\.com$ [NC]
RewriteRule ^/?$ http://www.sample.com/default.php?from=%1 [L,P]
Will take the request http://www.example.com/ and invisibly proxy it to http://www.sample.com/default.php?from=example. The browser's URL address bar will remain http://www.example.com/.
Note that the rule only matches against the request URI /. If you want to do more, you'd have to create the correct regular expression and grouping.
If you have redirects on the sample.com site, you'll need to employ ProxyPassReverse to rewrite the redirects. Also see ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath if there are cookies involved.
If you can do this in vhost or server config instead, then consider simply using ProxyPass instead of mod_rewrite. The ProxyPass directive won't work inside htaccess files.
EDIT:
Seeing as how everything is in the same document root, you won't need to proxy anything. Simply:
RewriteCond %{HTTP_HOST} !^www\.sample\.com$ [NC]
RewriteCond %{HTTP_HOST} ([^.]+)\.com$ [NC]
RewriteRule ^/?$ /default.php?from=%1 [L]
I use online generators.
Use this generator: mod-rewrite

htaccess rewrite ".../pages/about.php" to ".../about"

I've searched and found a lot of questions on this site and elsewhere that are very similar, but I've tried implementing and modifying all the suggestions I've found and none of it works. I realize this is a very basic question an I am extremely frustrated because nothing I'm trying is working.
With that having been said... I am trying to organize my content pages within kurtiskronk.com/pages/... (e.g. kurtiskronk.com/pages/about.php)
What I want to do is make it so that I can simply link to kurtiskronk.com/about ... So how do I go about stripping "pages/" and ".php"? I don't have a ton of content pages, so it's not a big deal if I have to specify for each page, though something dynamic would be handy.
NOTES: I am using Rackspace Cloud hosting, and WordPress is installed in /blog. My phpinfo() can be seen at http://kurtiskronk.com/pages/phpinfo.php
This is my existing .htaccess file (in the root)
php_value register_globals "on"
Options +FollowSymLinks
RewriteEngine On
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
RewriteBase /
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [L]
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
# PHP - MAIL
php_value mail.force_extra_parameters -kurtis#kurtiskronk.com
I tested and the rewrite works with the line below (/about as URL brings up file /pages/about.php), but then the homepage gives a 500 Internal Server Error:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
So I'm still sort of in the same boat as before, and as a follow-up, possibly more difficult question, if you go to http://kurtiskronk.com/weddings I am using SlideShowPro (flash) w/ SSP Director (self-hosted) as the back-end for it. When it pulls up a new image, it adds the following after /weddings ... "#id=album-152&num=content-9698"
There are four sections of the portfolio
# Homepage (kurtiskronk.com) id=album-148 ($id is constant for this section)
# Weddings (/weddings) id=album-152 ($id is constant for this section)
# Portraits (/portraits) id=album-151 ($id is constant for this section)
# Commercial (/commercial) id=album-150 ($id is constant for this section)
Assuming we get kurtiskronk.com/weddings to rewrite successfully without breaking anything, how would we make the total URL something cleaner kurtiskronk.com/weddings/9698 since the $num is the only thing that will change within a given section?
Kurtis, thanks for the extra information. It's a lot easier to give a specific answer to this.
My first comment is that you need to separate out in your thinking URI space -- that is what URIs you want your users to type into their browser -- and filesystem space -- what physical files you want to map to. Some of your mappings are URI->URI and some are URI->FS
For example you want to issue a permanent redirect of www.kurtiskronk.com/* to kurtiskronk.com/*. Assuming that you only server the base and www subdomains from this tree, then this cond/rule pair should come first, so that you can assume that all other rules only refer to kurtiskronk.com.
Next, you need to review the RewiteBase documentation. .htaccess files are processed in what Apache calls a Per-Directory context and this directive tells the rewrite engine what to assume as the URI base which got to this directory and .htaccess file. From what I gather, your blog is installed in docroot/blog (in the filesystem, and that you want to get to directory by typing in http://kurtiskronk.com/blog/ but that this .htaccess file is for the root folder -- that is the base should be (this goes before the www mapping rule)
DirectorySlash On
DirectoryIndex index.php
RewriteBase /
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
You can add some field dumps look for REDIRECT_* in the Server or Environment table in the phpinfo O/P to see if these are sensible. For example:
RewriteWrite ^(.*)$ - \
[E=TESTDR:%{DOCUMENT_ROOT}/pages/$1.php,E=TESTPDR:%{DOCUMENT_ROOT}/pages/$1.php]
Your next rule is that if the file exists in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [NS,L]
[Note that some shared service sites don't set up DOCUMENT_ROOT properly for the rewrite engine so you may need to run a variableinfo script (<?php phpinfo(INFO_ENVIRONMENT | INFO_VARIABLES); to see if it sets up alternatives. On your site you have to use %{ENV:PHP_DOCUMENT_ROOT} instead.]
Your next rule is that if the file exists, but with the extension .php in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [NS,L]
Now redirect any blog references to the blog subdirectory unless the URI maps to a real file (e.g. the blog stylesheets and your uploads.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
A complication here is that WP may be using a poorly documented Apache feature call Path Info that is a script can act as a pseudo directory so http://kurtiskronk.com/blog/tag/downtown/ is redirected to docroot/blog/index.php/tag/downtown/ which is then executed by `docroot/blog/index.php using /tag/downtown/ as the PATH_INFO. But this is one for Wordpress experts to comment on. If this last rule doesn't work then try:
RewriteRule ^blog/(.*) blog/index.php/$1 [L]
PS. I like your site. I wish I was that young again :(
Postscript
When you say "it doesn't work", what doesn't with this .htaccess?
http://kurtiskronk.com/phpinfo,
http://kurtiskronk.com/phpinfo.php,
http://kurtiskronk.comblog/tag/downtown/
It's just that these rules work for these tests (with domain swapped) on mine. (One way is to move or copy the above variableinfo.php to the various subdirectories. If necessary temporarily rename the index.php to index.php.keep, say, and copy the variableinfo.php to the index.php file. You can now enter the various URI test patterns and see what is happening. Look for the REDIRECT_* fields in the phpinfo output, and the SCRIPT_NAME will tell you which is being executed. You can add more {E=...] flags to examine the various pattern results. (Remember that these only get assigned if the rule is a match.
Lastly note the changes above especially the additional NS flags. For some reason mod_rewrite was going directly into a subquery which was resulting in redirect: being dumped into the file pattern. I've had a look at the Apache code and this is a internal botch to flag that further redirection needs to take place (which then replaces this or backs out). However this open bug indicates that this backout can be missed in sub-queries and maybe that's what is happening here. Certainly adding the NS flas cured the problem on my test environment.
PS. Note the added explicit DirectoryIndex directive and also that whilst http://kurtiskronk.com will run the root index.php, the explicit /index.php version will run the one in pages, because that's what your rules say.
Here is a simple solution. You can use it apache conf file(s) or in .htaccess (easier to set up when you're trying).
mod_rewrite has to be enabled.
For example, use .htaccess in your DocumentRoot with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
It will redirect /about to /pages/about.php, and any other page.
The "RewriteCond" part is to authorize access to an existing file (eg: if you had an "about" file at the root of your site, then it will be served, instead of redirecting to /pages/about.php).
Options +FollowSymLinks
RewriteEngine On
RewriteRule /([0-9]+)$ /pages/$1.php [L]
Put something like this in your .htaccess file. I guess that is what you want.
Juest a redirect from a simple url to a longer url.

Categories