Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is it possible to set the active folder? 1

Status
Not open for further replies.

theniteowl

Programmer
May 24, 2005
1,975
US
I am using an HTACCESS file to intercept and redirect requests through a PHP page.
My Index.php acts as a template showing the page structure and navigation controls and then loads the requested page into the content area of the template.

The issue is that the template loads from the root folder.
After the redirection occurs the root folder is the active folder. The index.php file uses the path to the requested page in order to do an include for that page.
The problem is that when people create their content pages they use relative paths from where that page resides on the server. So if they have a link to another page or image in the same folder simply using href="otherfile.htm" will not work since the active folder is actually the root folder.

Is there a command available that will change the active folder to the one I load the requested page from?
I would like to redirect to my template and let it load the page structure then alter the active folder to the one it is about to do the include from so once the page is rendered the paths work normally without them having to always remember to use full paths for every link.

Thoughts?
I have asked in the PHP forum but have not yet heard from anyone. I wondered if there was something specifically related to Apache that I could use.

Thanks.

At my age I still learn something new every day, but I forget two others.
 
Well nuts!
It sounded like this should do what I want but it does not seem to be working.

I used this:
chdir($strfolder);
echo getcwd() . "\n";

$strfolder contains the name of the subfolder.
The index.php executes in /jfk/jfk2 and the target file to load is /jfk/jfk2/library/library.htm
$strfolder contains the word library parsed from the path.
I execute the chdir command then echo getcwd and it shows me the path being /jfk/jfk2/library but in the rendered page all the links show the path as /jfk/jfk2/whatever.htm.

I tried using chdir just prior to the include statement for library.htm, just after the include statement and at the very end of the index.php page to see if it had any effect and though getcwd always shows me the correct directory the page still renders with the paths relative to the jfk2 folder rather than library.

I will keep playing with it but let me know if you have any ideas. The fact that I am inside an executing script as this happens might have something to do with it setting the path back again but I am just guessing. Or chdir acts as a method to alter the pointer to where to look for files but not the current operating path for the pages themselves.



At my age I still learn something new every day, but I forget two others.
 
Hi

I played abit with this. This works for me.
Code:
[highlight antiquewhite]   directory structure   [/highlight]
|-[[b]DOCUMENT_ROOT[/b]]
|  |-[[b]ONE[/b]]
|  |  |-[[b]TWO[/b]]
|  |  |  +-second.txt
|  |  |-first.txt
|  |  +-logo.png
|  |-.htaccess
|  |-base.txt
|  +-index.php

  
[highlight antiquewhite]   .htaccess   [/highlight]
RewriteEngine on
RewriteRule .*\.htm /index.php?file=%{REQUEST_URI}


[highlight antiquewhite]   index.php   [/highlight]
<html>
<body>
<?php
include $_SERVER[DOCUMENT_ROOT].preg_replace('/\.htm$/','.txt',$_GET[file]);
?>
</body>
</html>


[highlight antiquewhite]   base.txt   [/highlight]
<img src="one/logo.png">
<h1>base</h1>
go to :
<ul>
<li><a href="one/first.htm">first</a></li>
<li><a href="one/two/second.htm">second</a></li>
</ul>


[highlight antiquewhite]   first.txt   [/highlight]
<img src="logo.png">
<h1>first</h1>
go to :
<ul>
<li><a href="../base.htm">base</a></li>
<li><a href="two/second.htm">second</a></li>
</ul>


[highlight antiquewhite]   second.txt   [/highlight]
<img src="../logo.png">
<h1>second</h1>
go to :
<ul>
<li><a href="../../base.htm">base</a></li>
<li><a href="../first.htm">first</a></li>
</ul>

Feherke.
 
feherke, I am not sure I understand how this works.
The htaccess ensures all requests are routed to the root folder and index.php essentially as mine does but I do not see how the working folder in terms of the rendered output is set as that of the included files folder.

What is your purpose for swapping out htm for txt?
Because the include files will in themselves not be complete HTML? Is there a system limitation or requirement that makes this necessary in the way it handles the include or is it just for following good standards?

My ultimate goal with this template system is to have it require as little extra effort as possible for the school to maintain their own site. I want to eliminate the need for them to use templates in the design of their own pages and just allow them to create their HTML page in whatever way they like and place it on the server without having to remember to do anything special to the files.
I may soon be working on a parser for their files that will read the whole HTML file and strip out the HTML, HEAD, BODY, etc tags and incorporate the rest of the content into the content section of my page assuring valid HTML get's rendered at least in the document structure.

The goal is a lofty one, have an imposed and automatic template system without the school having to change their normal process for creating/maintaining their pages but I think I will eventually get it. So far the only real drawbacks have been forcing full paths for links and an inability to maintain anchor tags in the URL after a url rewrite.


At my age I still learn something new every day, but I forget two others.
 
Hi

theniteowl said:
I do not see how the working folder in terms of the rendered output is set as that of the included files folder.
There is no change to any folder. All processing happens in the root directory, where index.php resides. It knows the original path from the REQUEST_URI which is enough.
theniteowl said:
What is your purpose for swapping out htm for txt?
None. Sorry for confusing you. Just ignore it.
theniteowl said:
Because the include files will in themselves not be complete HTML?
I usually suggest it, because I think it keeps sources easier to maintain. But there is no such restriction.
theniteowl said:
allow them to create their HTML page [gray](...)[/gray] without having to remember to do anything special to the files.
Then better install a blog engine. That is for those who want site and does not want to learn how to create it.
theniteowl said:
So far the only real drawbacks have been forcing full paths for links and an inability to maintain anchor tags in the URL after a url rewrite.
Hmm... Am I bad if I suppose that you did not tried my example ?

The Rewrite Engine changes parts of the requested URL internally. So other resource will be served, but the client will not be notified about that.

Feherke.
 
feherke said:
Hmm... Am I bad if I suppose that you did not tried my example ?

I have not tried it directly, I have been trying to adapt your method into my existing site to see if I can get it to work but no luck so far.
I cannot get to my own server from work to set up a new site for testing and I did not want to disturb the working version of the schools site changing the htaccess file so I may have to wait until I get home to try your code there.

feherke said:
The Rewrite Engine changes parts of the requested URL internally. So other resource will be served, but the client will not be notified about that.

I am using rewrites already. I first rewrite to proc.php passing the URI, then I build a new URL and redirect to index.php passing the original values on the querystring.

Essentially what I am already using works similar to what you setup above except that my include statement uses a relative path from the root to the requested file like this:
Code:
  $filepath=substr($mypath,strlen($rootpath));
  // check if the file exists
  if (file_exists($filepath))
  {
    include($filepath);
  }
  else
  {
    // display error if not
    echo '
    <center><br><br><b><font color="#FFCC00" face="Arial" size="2">Sorry there is an error with this page.</font></b><br>
    <a href="javascript:history.back()">go back</a></center><br><br>';
  }

In the above code assume that $filepath equals library/library.htm
The folder the index.php file executes from is /jfk/jfk2/

The library page loads perfectly from the include but inside that page is: href="readinglist.htm"
When that link is clicked or even hovered over it is interpreted to be /jfk/jfk2/readinglist.htm rather than /jfk/jfk2/library/readinglist.htm.
So execution is still from /jfk/jfk2/ and the link tries to work relative from there rather than from the folder that page was included from and the path my rewriterule gets is an invalid one.

I do not know if the difference is environmental, something to do with the way my rewriterule is operating or just something I do not understand about the include statement you are using versus mine.


At my age I still learn something new every day, but I forget two others.
 
Hi

theniteowl said:
I did not want to disturb the working version of the schools site changing the htaccess file so I may have to wait until I get home to try your code there.
Set up a virtualhost for the tests [3eyes].
theniteowl said:
I first rewrite to proc.php passing the URI, then I build a new URL and redirect to index.php passing the original values on the querystring.
Not sure why that way. Could you post those directives ?

The difference between the two methods has to be that you redirect.

Feherke.
 
feherke said:
Set up a virtualhost for the tests .
I am new to Apache and not just puzzeling my way through. I could figure out how to setup a virtualhost but for the school site I do not have anything but FTP access to the folders the site resides in. When I am at home I can do whatever I need to with my own server for testing.

The htaccess file is this:
Code:
RewriteEngine on
# If request is for default.htm/html or index.htm/html redirect it to index.php
RewriteCond %{REQUEST_URI} ^/jfk/jfk2/(default|index)\.(html?) [NC]
RewriteRule ([^.]+\.(html?|php[45]?))$ /jfk/jfk2/index.php [R,L]

# If request is NOT for proc.php or index.php then redirect to proc.php passing the URI and querystring as params.
RewriteCond %{REQUEST_URI} !^/jfk/jfk2/(proc|index)\.php$ 
RewriteRule \.(html|htm|php|php4|php5)$ /jfk/jfk2/proc.php?url=%{REQUEST_URI}&%{QUERY_STRING} [R]

When this occurs it does not change the browsers displayed URL so bookmarking pages or even visually seeing what page you are on looking at the URL was not working.
So I rewrite the URL to proc.php which does this:
Code:
<?PHP
$mypath = '';
if (isset($_GET['url']))
{
  $mypath = '?url=' . $_GET['url'];
}
//Loop through querystring and create new string with only relevant parameters.
$qrystr = '';
foreach ($_GET as $key => $value)
{
  if ($key != 'url' and $key != 'tnav' and $key != 'mnav' and $key != 'cpath' and $key != 'anc')
  {
    $qrystr .= '&' . $key . '=' . $value;
  }  
}
$nextpage = "index.php" . $mypath . $qrystr;
header("Location: " . $nextpage);
?>

The above code needs to be revised to eliminate testing for certain parameters. An older revision of the site required them.
Essentially though I grab the querystring parameter called 'url' and use it to build the redirection string to index.php.
When index.php loads it displays the newly revised URL in the address window. I then parse out the requested path and any other parameters to use setting up the dynamic navigation controls and determine which content page to load.

It probably is the redirect causing the difference between your test code and my own. I can test it out at home to see but without the redirect I have other issues.

I have gotten the links to work relatively by building and writing out a <base> tag stating a base href and setting it to the requested folder. Though if there is a server-side way to handle this it would be much cleaner than injecting HTML that might somehow come into conflict with what the clients put into their own content pages.


At my age I still learn something new every day, but I forget two others.
 
Hi

theniteowl said:
RewriteRule ([^.]+\.(html?|php[45]?))$ /jfk/jfk2/index.php [[red]R[/red],L]

RewriteRule \.(html|htm|php|php4|php5)$ /jfk/jfk2/proc.php?url=%{REQUEST_URI}&%{QUERY_STRING} [[red]R[/red]]

When this occurs [red]it does not change the browsers displayed URL[/red] so bookmarking pages or even visually seeing what page you are on looking at the URL was not working.
Sorry, but there is something wrong.
mod_rewrite.html said:
'redirect|R [=code]' (force redirect)
Prefix Substitution with [ignore][:thisport]/[/ignore] (which makes the new URL a URI) to force a external redirection. If no code is given, a HTTP response of 302 (MOVED TEMPORARILY) will be returned. If you want to use other response codes in the range 300-400, simply specify the appropriate number or use one of the following symbolic names: temp (default), permanent, seeother. Use this for rules to canonicalize the URL and return it to the client - to translate ``/~'' into ``/u/'', or to always append a slash to /u/user, etc

So when you use the [tt][R][/tt] flag :
[ul]
[li]The server sends back the [tt]302 Found[/tt] response and a [tt]Location[/tt] header with the new URL[/li]
[li]The client sends the request for the new URL[/li]
[li]The server sends back the [tt]200 Ok[/tt] response and the document[/li]
[/ul]
This means the new URL must appear in the browser's location/address bar.
theniteowl said:
It probably is the redirect causing the difference between your test code and my own. I can test it out at home to see but without the redirect I have other issues.
Share them with us.
theniteowl said:
I have gotten the links to work relatively by building and writing out a <base> tag stating a base href and setting it to the requested folder. Though if there is a server-side way to handle this it would be much cleaner than injecting HTML that might somehow come into conflict with what the clients put into their own content pages.
I neither like the [tt]base[/tt] tag, but in situations like this is useful. The problem is that the browser thinks the files like they are in the root. No much to do against this, excepting using the Rewrite Engine without redirecting.

Feherke.
 
feherke said:
So when you use the [R] flag :

The server sends back the 302 Found response and a Location header with the new URL
The client sends the request for the new URL
The server sends back the 200 Ok response and the document
This means the new URL must appear in the browser's location/address bar.

I am not very familiar with Mod_Rewrite and have been piecing this together from lots of samples and suggestions.
I DID have a problem with the URL not changing with just the RewriteRule but at that time I was probably using different code that may not have used the [R] flag.
I do not know the commands and syntax well enough to understand all of the implications, I have just been tweaking the code bit by bit until I got the desired result.

Perhaps I can now do away with the proc.php file and go directly to index.php which might clear up the relative link problems. I will have to test it and see what happens.

I was also trying to find a method of preserving anchor tags passed on the address line which may have been one of the reasons for having an intermediate script. I have been working on this sporadically for a long time and cannot clearly recall all of the former reasons for some of the approaches and later alterations may have made some portions unnecessary.

My htaccess file is not fully optimized yet either.
Ultimately I want to first test if the request was to the old link other sites have so that I can redirect it to the index.php file, then I want to stop the htaccess file from processing any requests to files in the root folder so I do not end up in loops and finally any request that did not fit the first sets of conditions would end up doing the RewriteRule to send to proc.php (maybe to be replaced by index.php).
Some of the examples I have been given on other sites do not work for reasons I do not understand yet but I am getting there slowly.
For instance, one suggstion for the last rewriterule above is to use a line like this:
Code:
RewriteCond $1 !^jfk/jfk2/(proc¦index)\.php$ 
RewriteRule ([^.]+\.(html?¦php[45]?)$ /jfk/jfk2/proc.php?url=$1 [QSA,R=302]
But any use of $1 in my htaccess file causes it to fail.
I can substitute with %{REQUEST_URI} and it works.

As difficult as all of this has been, when it is finished it will actually be very little code to make the whole template work. It's just frustrating trying to figure it all out. :)



At my age I still learn something new every day, but I forget two others.
 
Hi

theniteowl said:
I was also trying to find a method of preserving anchor tags passed on the address line
Do you mean the red part from below ?

[ignore][/ignore][red]#section[/red]

That is not sent to the server. The browser cuts it off and keeps until the document arrives, then applies the jump in the document.
theniteowl said:
RewriteCond [red]$1[/red] !^jfk/jfk2/(proc¦index)\.php$p
The backreferences starting with dolar sign ( $ ) referes to a group captured by a [tt]RewriteRule[/tt] directive. Do you have such before that line ?

Feherke.
 
feherke said:
Do you mean the red part from below ?


That is not sent to the server. The browser cuts it off and keeps until the document arrives, then applies the jump in the document.
I found info on another site saying that a bit of CGI combined with htaccess can achieve the preservation of the anchors but have had no success with it myself.

With the old version of my site the anchor was lost entirely. Going directly to Index.php however the anchor does get interpreted by IE even after the rewrite though the anchor data on the URL disappears. I have not tested this in Firefox yet. So at least the page does move to the indicated position but the info is lost if the user tries bookmarking. It saves the page address without the anchor.

feherke said:
The backreferences starting with dolar sign ( $ ) referes to a group captured by a RewriteRule directive. Do you have such before that line ?

I do not understand the question. Here is the code that was suggested to me.
Code:
RewriteEngine on 
RewriteCond $1 !^jfk/jfk2/(proc¦index)\.php$ 
RewriteRule ([^.]+\.(html?¦php[45]?)$ /jfk/jfk2/proc.php?url=$1 [QSA,R=302]

So apparently nothing is captured prior to this so $1 would be invalid? I have not seen an example of how that would be captured and so do not understand it yet.

At my age I still learn something new every day, but I forget two others.
 
Hi

theniteowl said:
I found info on another site saying that a bit of CGI combined with htaccess can achieve the preservation of the anchors
Please install LiveHTTPHeaders for FireFox and/or ieHTTPHeaders for Explorer to see the HTTP communication between client and server.

For example I visited the following address, and see below the requests the browsers sent to the server.


Code:
[highlight antiquewhite]   FireFox   [/highlight]
GET /wiki/World_Wide_Web HTTP/1.1
Host: en.wikipedia.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.8
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

[highlight antiquewhite]   Explorer   [/highlight]
GET /wiki/World_Wide_Web HTTP/1.1
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: en.wikipedia.org
Connection: Keep-Alive
theniteowl said:
So apparently nothing is captured prior to this so $1 would be invalid? I have not seen an example of how that would be captured and so do not understand it yet.
Yes, that is what I want to say. Capturing is done by grouping with parenthesis ( () ).
Code:
RewriteEngine on
RewriteCond [purple][b]$1[/b][/purple] !^jfk/jfk2/[highlight #eef][blue][b]([/b][/blue]proc¦index[blue][b])[/b][/blue][/highlight]\.php$
RewriteRule [highlight #efe][green][b]([/b][/green][^.]+\.[red][b]([/b][/red]html?¦php[45]?[green][b])[/b][/green][/highlight]$ /jfk/jfk2/proc.php?url=[green][b]$1[/b][/green] [QSA,R=302]

[COLOR=#f9f #f9f]::[/color] [gray]- error, nothing captured  previously[/gray]
[COLOR=#99f #99f]::[/color] [gray]- could be referenced by [b]%1[/b] if needed[/gray]
[COLOR=#9f9 #9f9]::[/color] [gray]- is referenced by the [b]$1[/b][/gray]
[COLOR=#f99 #f99]::[/color] [gray]- error, unbalanced delimiters[/gray]

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top