Nginix Routing For Wordpress - wordpress

I'm trying to get Nginx and Wordpress to play nice together.
Most of the documentation I've found talks about how to set up Nginx rewrite rules for WP Multisite configurations, but I'm trying to do something slightly different, where I'm looking to load data from an API and populate a template wordpress page, but have the url as the last path component.
For example I'm trying to load a page with a URL like this…
http://example.com/article/{the-slug}
When loading this page we want to redirect to a Wordpress page located at a permalink of this
http://example.com/article
We do no want to load any post content from the existing word press site,
We simply always go to this page when any url matching /article/{slug} is matched, and pass off the slug parameter behind the scene.
We have a WP Rewrite rule in place in our theme’s functions.php
/**
* Intercept the articles request
* #return void
*/
function custom_rewrite_rule() {
add_rewrite_rule('^article/([^/]*)/?','index.php/article?slug=match[1]','top');
}
add_action('init', 'custom_rewrite_rule’);
When running in Apache everything works exactly as expected when the following rules specified in the .htaccess file.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^^article/([^/]*)/? /index.php/article?slug=match[1] [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
However I’ve tried to convert this to run on Nginx with no success.
Some variations I’ve used for the location directive are
location / {
rewrite ^/^article/([^/]*) /index.php/article/?slug=match[1];
try_files $uri $uri/ /index.php$query_string;
}
And
location / {
try_files $uri $uri/ ^article/([^/]*)/? /index.php/article?slug=match[1];
try_files $uri $uri/ /index.php$query_string;
}
And even a combo of these together.
location /article {
try_files $uri $uri/ ^article/([^/]*)/? /index.php/article?slug=match[1];
}
location / {
try_files $uri $uri/ /index.php$query_string;
}
But I’m really stumped on the actual syntax to get this to work
Any advice would be greatly appreciated.
Thanks.
Update
I've been logging rewrites in Nginx and things there look like they're doing exactly what they should
2016/06/16 02:56:52 [notice] 12879#12879: *1 "^/article/(.+)" matches "/article/test-article", client: 192.168.10.1, server: example.com, request: "GET /article/test-article HTTP/1.1", host: "example.com"
2016/06/16 02:56:52 [notice] 12879#12879: *1 rewritten data: "/index.php/article", args: "", client: 192.168.10.1, server: example.com, request: "GET /article/test-article HTTP/1.1", host: "example.com"
And if I place this url in the browser http://example.com/index.php/article/, I go exactly where i want the rewrite to take me.

Related

Laravel with Wordpress blog (with WP API)

My progect structure
/root_dir
/app
/bootstrap
...
/public
index.php
.htaccess
/wp #wordpress installation here
/wp-admin
/wp-content
/wp-includes
index.php
.htaccess
...
So what I want to acomplish is to have Laravel project with views, API etc
And I need wordpress only for one route domain.com/blog where I'll have separate default WP blog that doesn't integrate or interact with my Laravel app in any way
My /public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_URI} !^(blog) #ADDED ONLY THIS MAGIC LINE
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
And my /public/blog/.htaccess is WP default
And it works like a charm!
My lara routes are fine... API routes - good... WP blog - great...
BUT
Now I want to call WP API, e.g. domain.com/blog/wp-json/wp/v2/posts
And all I see is Laravel's "NOT FOUND" page
Please help!
I have a strong feeling it can be solved with .htacess 'magic' but unfortunately I'm noob in that...
P.S. Found a similar question here Laravel project next to Wordpress project (in public_html folder)
But I need vice versa solution
you can proxy pass the address http://example.com/blog to some other address,
for example using nginx :
server {
listen 80;
server_name blog.example.com;
location / {
root /var/www/wordpress;
try_files $uri /index.html;
}
}
server {
listen 80;
server_name example.com www.example.com;
location / {
root /var/www/laravel;
try_files $uri /index.html;
}
location /blog/ {
proxy_pass http://blog.example.com/;
}
}
This is a simple and also clean way, and also you don't need to change even one line of code to have laravel and wordpress aside each other.
Holy cow!
The solution was to navigate to dashboard/settings/permalinks and change option from 'plain' to any other!
Found the answer here https://wordpress.org/support/topic/rest-api-in-wp-4-7/#post-8620246
You need to be using pretty permalinks to access /wp-json/. If you’re not, you can instead use ?rest_route=/ to get the index and ?rest_route=/wp/v2/posts (e.g.) for specific routes.

Wordpress Error 404 after changing permalink on some pages

I’m having a problem since changing my permalinks from default to postname on a wordpress site. I’m getting 404 errors on pages but only the ones that are within the submenu called menus, all the other pages are working fine.
I have been searching on and off for an answer to this for a couple of days now with no success. Someone suggested that it might be an error in the HTaccess file but I don't really know what I'm looking at. I tried generating a new one from Wordpress.org code I found but that just killed the site altogether so I changed it back to the old one. I can see the .htaccess inside the folder public_html there are some others in there with .bak which I assume are from backups I've made of the site. Here is a link to what I'm getting http://www.5thview.com/menus/nibbles/
Not sure why it’s just those pages that are affected other than they are in a submenu. I’ve no idea how to fix this.
I should add that if I switch back to default permalinks it works fine again…
I would need specific instructions if poss as I'm a bit of a newb to the coding side etc although I can find my way around if directed...
Any help would be greatly appreciated. Thanks...
The reason links are broken is that your host doesn't have root directive correctly set.
If you are using Nginx, change the virtual host conf file as below:
server{
location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}
}
If your root wordpress is not the webroot but http://[domain.com]/wordpress/:
server{
location /wordpress/ {
    try_files $uri $uri/ /wordpress/index.php?q=$uri$args;
}
}
Don't forget to restart nginx service.
If you are using Apache, put .htaccess file under your root path, an add below lines
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Don't forget to restart apache service.

How to rewrite based on accept heads in nginx

I recently switched over to nginx and am fairly new at it, so forgive me if this has been covered extensivly before.
What im trying to do is rewrite the user request based on tthe accept header sent out.
In paticular:
if the accpet header is an image/gif or image/webp then serve the image, if not concat off the .gif of the url and serve that.
hears my apache configuration, but again im on nginx now and trying to learn how i could convert it over:
RewriteCond %{HTTP_ACCEPT} ^image/gif [NC]
RewriteCond %{HTTP_ACCEPT} ^image/webp [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com(.*)$ [NC]
RewriteRule ^i/(.*)\.gif http://example.com/i/$1 [R=302,L]
as you can see the above htaccess file works like a charm, but nginx is completly different it seems.
Ive done some reading and come up with this:
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
with the following inside the server block
location ~* ^/i/.+\.(gif)$ {
root /storage-pool/example.com/public;
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
Sadly, this doesnt work and I still dont know how to trouble shoot in nginx either.
Any information would be greatly appreciated, thanks.
From your location, the try_files will concat $uri with $webp_suffix which might not what you want, for example if you have a request to /i/test.gif with HTTP_ACCEPT header set to image/webp your location config above will try to find files at:
/storage-pool/example.com/public/i/test.gif.webp
You probably want something like this below instead:
location ~* ^(?P<basename>/i/.+)\.gif$ {
root /storage-pool/example.com/public;
add_header Vary Accept;
try_files $basename$webp_suffix $uri =404;
}
This location will capture the image path without the .gif suffix and it will be available as variable named $basename
More information about named capture here: http://nginx.org/en/docs/http/server_names.html#regex_names

root defaults to welcome to Nginx when using a "greedy" location

It seems like similar questions have been asked consistently on the site, but despite of browsing dozens of similar questions, none of the solutions seem to work for me.
When I go to mydomain.com, then nginx shows the default "welcome to nginx" page, however, when I visit mydomain.com/whatever/blablabla/whatever then Nginx sends the user to index.php?q=$uri which is the expected behavior.
So the problem only happens when visiting the actual root domain: mydomain.com.
This is my default file:
server {
listen 80;
location / {
include /etc/nginx/include/php;
index index.php;
root /var/www/mydomain.com/current/web;
}
location ~ /(.*)/? {
try_files $uri $uri/ /index.php?$uri;
}
}
Under that configuration, visiting mydomain.com defaults to "welcome to nginx" page, but mydomain.com/whatever is sent to index.php as expected.
When I tweak that to, something like:
location ~ /^(.*)/?$ {
try_files $uri $uri/ /index.php?$uri;
}
or
location ~ /^.*/? {
try_files $uri $uri/ /index.php?$uri;
}
then mydomain.com starts working again, but mydomain.com/whatever starts showing a 404 page. I've tried a bunch of different configurations, but none of the configurations I've tried seem to fully work as I expect.
Basically what I want is pass the whole URL to a front controller, to parse it and take actions depending on the contents of such URL.
If it helps, I want to mimic in Nginx this behavior from Apache:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php
I also have another virtual host:
server {
listen 0.0.0.0:443;
root /var/www/mydomain.com/current/web;
index index.html index.php;
fastcgi_param HTTPS on;
include /etc/nginx/include/ssl;
include /etc/nginx/include/php;
}

Pinnect's htaccess rules to nginx

so I've been playing around with the rules trying to transform them, the pinnect script's rules are:
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
#RewriteBase /
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
# fix for uploadify 302, 406 errors
SetEnvIfNoCase Content-Type "^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
I have pinnect on pinnect/ on the server, however VB is running on the index for now,
I've tried
location /pinnect {
try_files $uri $uri/ /index.php;
}
And different variations of that, however let's say I go to the /install directory - it tries to redirect me to pinnect/forums.php(because of VB), if I try to go to index.php directly, an endless loop occurs, anyone could give me a hand with this?
EDIT:
So i've got this rule currently
location ~ ^/pinnect/index.php { try_files maintenance.html #index.php; }
location ~ ^/pinnect/ {
rewrite ^/pinnect$ /pinnect/index.php last;
rewrite ^/pinnect/$ /pinnect/index.php last;
#rewrite ^/pinnect/([^.]+)$ /pinnect/index.php/$1 last;
rewrite ^/pinnect/(.*) /pinnect/index.php/$1 last;
}
However where ever I go, I get a 301, 302 so it's not behaving same way as the htaccess, could anyone help?
If it's just a matter of status code returned, you might have to use return instruction on your location block.
location ~ ^/pinnect/index.php { try_files maintenance.html #index.php; }
location ~ ^/pinnect/ {
rewrite ^/pinnect$ /pinnect/index.php last;
rewrite ^/pinnect/$ /pinnect/index.php last;
#rewrite ^/pinnect/([^.]+)$ /pinnect/index.php/$1 last;
rewrite ^/pinnect/(.*) /pinnect/index.php/$1 last;
return 200;
}
Read more…
As we are here, you should replace last by break since you have your instructions in a location block.
Also, you might prefer using ? instead of (.*) to drop the original arguments.
Read more…

Resources